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

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

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

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

最佳答案

对于这么多功能,您可能应该 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 对象,以便它只加载出现在 map 边界内的数据——这应该使您的 map 保持相对快速。为此,请使用 map object's “空闲”事件(本地图在平移或缩放后完成渲染时触发)以根据 map object's bounds/extent coordinates 获取相关数据.基本上,您的事件处理程序将向您的服务层(PHP、Ruby、C# 等)发出 ajax 请求以执行 a spatial query like ST_Intersects。 ,它将仅返回 map 区域内的要素。如果您的查询返回 GeoJSON geometry expressions from the ST_AsGeoJSON function ,您应该能够毫不费力地将它们直接推送到 Google map 中。

设置: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

JavaScript:示例 map 的“空闲”事件监听器,它捕获空闲事件并创建 Well Known Text Polygon 以在 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 脚本,用于选择落在 map 对象边界/范围内的任何记录:

<?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,每一步都有陷阱和注意事项,并且可能有更好的方法来做至少一些事情。所以让我强调不要把这当成福音!

关于javascript - GIS 谷歌地图处理大 # 多边形添加/删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22941003/

相关文章:

javascript - 使用 ReactJs 创建的页面未被谷歌索引

javascript - 给定一个 URL,我怎样才能找到 anchor HTML anchor 标签?

javascript - 为什么 React-Toastify v.9 中的 toast.update 不能正常工作

ios - 使用 google map API 插入文本说明

css - Bootstrap 2.3.2 干扰 Google map 控件 v.3

javascript - 删除谷歌地图中以前的标记并加载新地点

php - 如何在谷歌地图中显示标记 从 mysql php 检索数据

java - 阿拉伯语的 Android Google map 标记标题显示空白

javascript - 外部 JSON 文件的标记未显示在谷歌地图中

php - 如何使用 JS 和 PHP 检查 LatLng 在 Google StreetView 中是否有效