GIS谷歌地图处理大#多边形添加/删除

时间:2014-04-08 15:07:34

标签: javascript google-maps google-maps-api-3 kml

我正在寻找一个基于网络/移动的应用程序。该应用程序旨在为最终用户提供地理空间信息。地理空间数据的来源是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

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

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

2 个答案:

答案 0 :(得分:4)

对于许多功能,您应该load your shapefile data into a database喜欢MySQL或PostGREsql with the PostGIS extension。我将推荐使用PostGIS的PostGREsql,因为您可以将数据查询为GeoJSON几何表达式Google Maps can render right out of the box,或使用open 3rd-party JavaScript library可选择使用的几何表达式。

接下来,您将要对地图对象进行连线,以便仅加载将出现在地图边界内的数据 - 这样可以使地图保持相对较快。为此,请使用map object's"空闲" event(在平移或缩放后完成地图渲染时触发)以获取map object's bounds/extent coordinates的相关数据。基本上,您的事件处理程序将向您的服务层(PHP,Ruby,C#等)发出ajax请求以执行a spatial query like ST_Intersects,这将仅返回地图区域内的功能。如果您的查询返回GeoJSON geometry expressions from the ST_AsGeoJSON function,您应该可以轻松地将它们直接推送到Google地图中。

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

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

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
});

使用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;
?>

JavaScript:render GeoJSON using the 3rd-party library的示例方法,如上所述:

<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>

我把它放在一起非常快,但希望它通过几个示例/片段展示具体步骤来传达整体想法。并且希望我没有错误地丢弃这些例子。 FWIW,每一步都有陷阱和警告,并且可能更好的方法来做至少一些事情。所以,我要强调不要把它当作福音!

答案 1 :(得分:1)

你看过Map Engine了吗?专为重型地理数据而设计

https://support.google.com/mapsengine/answer/3342103?hl=en