GIS Google Maps 处理大 # 多边形添加/删除

use*_*973 2 javascript google-maps kml google-maps-api-3

我正在寻找一个基于网络/移动的应用程序。该应用程序旨在为最终用户提供地理空间信息。地理空间数据的来源是 ESRI Shapefiles。我对谷歌地图有一点经验,所以我考虑将这些转换为 KML,然后将该 kml 文件解析为数据库。一些核心功能如下

+Display 2000 markers with different icons
++have styled info window on this marker
+++ability to add/remove polygons from map related to this marker
+Display ~4000 polygons

Filters
+add/remove markers/polygons based on attribute filters
Run Code Online (Sandbox Code Playgroud)

我认为我需要克服的最大障碍是让这张地图既具有交互性又保持性能。一项功能是动态添加/删除特定多边形的能力。过去,我通过 KML 文件渲染了大量多边形。但是,由于我需要一次从该文件中添加/删除 1 或 2 个多边形,因此我不确定如何实现。

有没有人对如何处理大量标记和多边形有任何建议,能够逐个删除/添加多边形?

elr*_*bis 5

对于这么多功能,您可能应该将 shapefile 数据加载到带有 PostGIS 扩展名的MySQL 或PostGREsql数据库中。我将推荐 PostGREsql 和 PostGIS,因为您可以将数据查询为GeoJSON几何表达式,Google Maps 可以立即呈现,或者您可以选择使用开放的 3rd-party JavaScript 库来使用它。

接下来,您需要连接地图对象,以便它只加载出现在地图边界内的数据——这将使您的地图保持相对快速。为此,请使用地图对象的“空闲”事件(在平移或缩放后地图完成渲染时触发)根据地图对象的边界/范围坐标获取相关数据。基本上,您的事件处理程序将向您的服务层(PHP、Ruby、C# 等)发出 ajax 请求,以执行类似 的空间查询ST_Intersects,这将仅返回地图区域内的要素。如果您的查询ST_AsGeoJSON函数中返回GeoJSON 几何表达式,您应该能够毫不费力地将它们直接推送到 Google 地图中。

设置:示例 OGR2OGR 调用将 ( -f) 一个 shapefile 转换为 PostGREsql/PostGIS,并将其 ( -t_srs)转换为 EPSG 4326(WGS 1984,又名经度/纬度坐标)。请注意,如果您的数据处于不寻常的投影中,则可能会有更多内容。

ogr2ogr -f "PostgreSQL" "PG:host=127.0.0.1 user=dbUSERNAME dbname=dbNAME 
password=dbPASSWORD" "C:/path_to/your_data.shp" -nlt GEOMETRY -lco PRECISION=no 
-t_srs EPSG:4326
Run Code Online (Sandbox Code Playgroud)

JavaScript:示例地图的“空闲”事件侦听器,可捕获空闲事件并创建用于 ST_Intersects 空间查询的众所周知的文本多边形。

google.maps.event.addListener(map, 'idle', function(event)
{
    var bounds = map.getBounds();
    var sw = bounds.getSouthWest();
    var ne = bounds.getNorthEast();

    // Redefine the sw..ne coordinates as a Well Known Text Polygon expression.
    var wkt = encodeURIComponent("POLYGON((" + sw.lng() + " " + sw.lat() + ", " + 
                                                sw.lng() + " " + ne.lat() + ", " +
                                                ne.lng() + " " + ne.lat() + ", " +
                                                ne.lng() + " " + sw.lat() + ", " + 
                                                sw.lng() + " " + sw.lat() + "))");

    // CALL SOME SERVER-SIDE METHOD HERE, SUBMITTING 
    // THE wkt PARAMETER FOR USE IN A SPATIAL QUERY.
    //
    // getGeoJsonData.php?bounds=wkt
});
Run Code Online (Sandbox Code Playgroud)

带有 PostGREsql/PostGIS 的 PHP:带有空间查询的示例 PHP 脚本,用于选择属于地图对象边界/范围内的任何记录:

<?php
// Required input
$ewkt = 'SRID=4326;' . urldecode($_GET["bounds"]);

// Future output
$json = '';

// Parameterized Query Spanning Multiple Lines
$query .= <<<EOD
SELECT 
  ST_AsGeoJSON(wkb_geometry) as geom, 
  field_1, 
  field_2, 
  field_n 
FROM
  your_data
WHERE 
  ST_Intersects(wkb_geometry, ST_GeomFromEWKT( $1 ));
EOD;

$conn = pg_pconnect('host=127.0.0.1 port=5432 dbname=dbNAME user=dbUSERNAME password=dbPASSWORD');

// Pass-in your bounds EWKT parameter..
$result = pg_query_params($conn, $query, array($ewkt));

if($result)
{
    while($row = pg_fetch_assoc($result))
    {
        $json .= '{"Feature": {';
        $json .= '"geom": "' . $row['geom'] . '",';
        $json .= '"field_1": "' . $row['field_1'] . '",';
        $json .= '"field_2": "' . $row['field_2'] . '",';
        $json .= '"field_n": "' . $row['field_n1'] . '",';
        $json .= "}}";
    }
}

echo $json;
?>
Run Code Online (Sandbox Code Playgroud)

JavaScript:使用上面提到的第 3 方库呈现 GeoJSON 的示例方法

<script type="text/javascript" src="GeoJSON.js"></script>
<script type="text/javascript">
    var featureOverlay = []; // Create an array to hold all of your features.

    // Pass your individual GeoJSON objects into a method like this.
    function renderGeoJSON(geoJSON)
    {
        var pOptions = {
          strokeColor: '#00FFFF',
          strokeOpacity: 1,
          strokeWidth: 2,
          fillColor: '#00FFFF',
          fillOpacity: 0
        };

        var featureGeoJSON = new GeoJSON(geoJSON, pOptions);

        if (featureGeoJSON.error)
        {
            alert('Errors detected in GeoJSON geometry expression.');
        }
        else
        {
            for(var i=0; i<featureGeoJSON.length; i++)
            {
                // Attach the feature to the map..
                featureGeoJSON[i].setMap(map);

                // Save a reference to the feature in your array..
                featureOverlay.push(featureGeoJSON[i]);
            }
        }
    }
</script>
Run Code Online (Sandbox Code Playgroud)

我很快就将它们组合在一起,但希望它通过一些演示特定步骤的示例/片段来传达整体想法。希望我没有在示例中乱扔太多错误。FWIW,每一步都有陷阱和警告,并且可能至少有一些更好的方法来做一些事情。所以让我强调不要把这当成福音!