【问题标题】:GIS Google Maps handle large # polygons add/removeGIS Google Maps 处理大型 # 多边形添加/删除
【发布时间】:2014-05-21 09:12:03
【问题描述】:

我正在确定一个基于网络/移动设备的应用程序。该应用程序旨在为最终用户提供地理空间信息。地理空间数据的来源是 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 个多边形,所以我不确定如何实现这一点。

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

【问题讨论】:

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


    【解决方案1】:

    对于这么多功能,您可能应该 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“idle”事件(在平移或缩放后地图完成渲染时触发)来针对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 地图中。

    设置:示例 OGR2OGR 调用,将 shapefile 转换 (-f) 为 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:示例地图的“空闲”事件侦听器,它捕获空闲事件并创建众所周知的文本多边形以在 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 的示例方法,使用上面提到的第 3 方库:

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

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

    【讨论】:

    • 非常感谢您的回复。我在看geoserver,但是没有足够的关于这个主题的文档。至少在我能理解的水平上。你的帖子已经给了我足够的信心,让我放心,这个功能是可能的。我将研究您发布的主题。谢谢!
    • @user3032973,感谢您的接受。如果你想继续使用 GeoServer,你可以考虑overlaying data using WMS layers。如果您的 GeoServer 实例不在为您的 Google Map 应用程序提供服务的同一台机器上,您可能需要使用服务器端语言来执行实际的 WMS 请求。
    • 没有足够的文档让我及时消化了解地理服务器。我需要在下周开始开发这个。还需要使用从 shapefile 保存的信息发送附加参数。我可以将它与 geojson 数组合并吗?
    • PostGIS 将为您提供原始的 GeoJSON 几何表达式。所以我不会将它与 GeoJSON 本身合并(尽管有可能)。我只需创建一个具有 GeoJSON 属性的通用要素对象,然后使用您想要包含的任何其他属性来扩展要素对象。
    【解决方案2】:

    您看过地图引擎吗?专为大量地理数据而设计

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

    【讨论】:

    • 我能够找到使用该服务的示例非常慢。似乎比服务器端的 kml 文件慢。
    • 看起来这可能是一个不错的可行选择。我没有找到任何例子。但是专业版是否允许您添加/删除多边形或标记?看起来您最多可以拥有 X 层。如果这不可行,我想知道企业版是多少。
    猜你喜欢
    • 1970-01-01
    • 2023-03-26
    • 2012-02-08
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 2012-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多