Javascript Openlayers投影,带有OSM样式的地图和GeoJSON矢量层

Javascript Openlayers投影,带有OSM样式的地图和GeoJSON矢量层,javascript,openlayers,openstreetmap,geojson,Javascript,Openlayers,Openstreetmap,Geojson,注意:我知道还有一个类似的问题,但还没有回答,我需要知道如何处理GeoJSON和OSM的混合投影 我很困惑。我在Android上使用OSMDroid API进行映射,并希望使用OpenLayers和GeoExt进行复制,但我在包含GeoJSON节点和动作事件时遇到了一个投影问题 我的互动程序集基于OSM,与此HTML/JS托管在同一个Web服务器上。请看下文。我意识到我的界限不起作用,我的预测可能完全错误。我一直在测试不同的组合 问题是我的地图显示正确且居中良好。然而: 我的GeoJSON功能节

注意:我知道还有一个类似的问题,但还没有回答,我需要知道如何处理GeoJSON和OSM的混合投影

我很困惑。我在Android上使用OSMDroid API进行映射,并希望使用OpenLayers和GeoExt进行复制,但我在包含GeoJSON节点和动作事件时遇到了一个投影问题

我的互动程序集基于OSM,与此HTML/JS托管在同一个Web服务器上。请看下文。我意识到我的界限不起作用,我的预测可能完全错误。我一直在测试不同的组合

问题是我的地图显示正确且居中良好。然而:

  • 我的GeoJSON功能节点太离谱了。它们位于不同的投影long/lat中,但我不知道如何将GeoJSON long/lat设置或转换为当前地图投影

  • 我的mapCtrl不工作。当我点击它时,lonlat是另一个投影(OSM投影坐标),我似乎无法转换它们)

  • 任何关于范围/界限实际工作方式的提示都将不胜感激

  • 有人能帮我提一点建议吗?叹息。。。我没有足够的耐心

    以下是我的完整JS,如下所示:

    var mapPanel, store, gridPanel, mainPanel, nodePop, mapPop;
    
    Ext.onReady(function() {
    
        var map, mapLayer, vecLayer;
        var lon = -70.885610;
        var lat = 38.345822;
        var zoom = 17;
        var maxZoom = 18;
    
    var toProjection = new OpenLayers.Projection("EPSG:4326");
    var fromProjection = new OpenLayers.Projection("EPSG:900913");
        var extent = new OpenLayers.Bounds(-1.32,51.71,-1.18,51.80).transform(fromProjection, toProjection);
    
        // Setup the node layer feature store and push it all into a vector layer
        vecLayer = new OpenLayers.Layer.Vector("vector");
        store = new GeoExt.data.FeatureStore({
            layer: vecLayer,
            fields: [
                {name: 'name', type: 'string'},
                {name: 'status', type: 'string'}
            ],
            proxy: new GeoExt.data.ProtocolProxy({
                protocol: new OpenLayers.Protocol.HTTP({
                    url: "data/sa.json",
                    format: new OpenLayers.Format.GeoJSON()
                })
            }),
            autoLoad: true
        });
    
        // Setup the basic map layer using OSM style tile retreival to pull tiles
        // from the same server hosting this service
        map = new OpenLayers.Map(
            'map', {
                controls:[
                    new OpenLayers.Control.Navigation(),
                    new OpenLayers.Control.PanZoomBar(),
                    new OpenLayers.Control.Attribution(),
                    new OpenLayers.Control.ScaleLine()],
                projection: toProjection,
                displayProjection: fromProjection,
                numZoomLevels: 20,
                fractionalZoom: true
            });
    
        mapLayer = new OpenLayers.Layer.OSM(
            "Local Tiles",
            "tiles/${z}/${x}/${y}.png",
            {
                zoomOffset: 17,
                resolutions: [1.194328566741945,0.5971642833709725,0.2985821416854863] // Zoom level 17 - 19
            });
    
        map.addLayers([mapLayer, vecLayer]);
    
        // Create a map panel
        mapPanel = new GeoExt.MapPanel({
                title: "Map",
                region: "center",
                map: map,
                xtype: "gx_mappanel",
                center: new OpenLayers.LonLat(lon, lat),
                zoom: zoom
        });
    
        // Create a grid panel for listing nodes
        gridPanel = new Ext.grid.GridPanel({
                title: "Nodes",
                region: "east",
                store: store,
                width: 275,
                columns: [{
                    header: "Name",
                    width: 200,
                    dataIndex: "name"
                }, {
                    header: "Status",
                    width: 75,
                    dataIndex: "status"
                }],
                sm: new GeoExt.grid.FeatureSelectionModel({
                    autoPanMapOnSelection: true
                    })
        });
    
        // Create the main view port
        new Ext.Viewport({
            layout: "border",
            items: [{
                region: "north",
                contentEl: "title",
                height: 150
            }, mapPanel, gridPanel]
        });
        var lonLat = new OpenLayers.LonLat(lon, lat).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());
        map.setCenter(lonLat, zoom);
    
    
        // Attach all the event driven stuff here...
        // Create a node selection pop up control
        function nodeAction(feature) {
            nodePop = new GeoExt.Popup({
                title: 'Node selected',
                location: feature,
                width: 200,
                html: "",
                maximizable: true,
                collapsible: true
            });
            nodePop.on({
                close: function() {
                    if(OpenLayers.Util.indexOf(vectorLayer.selectedFeatures, this.feature) > -1) {
                        selectCtrl.unselect(this.feature);
                    }
                }
            });
            nodePop.show();
        };
    
        // Attach the pop to node/feature selection events
        var selectCtrl = new OpenLayers.Control.SelectFeature(vecLayer);
        vecLayer.events.on({
            featureselected: function(e) {
                nodeAction(e.feature);
            }
        });
    
        // Create map selection pop up control
        function mapAction(lonlat) {
            mapPop = new GeoExt.Popup({
                title: 'Map selected',
                location: lonlat,
                width: 200,
                html: "You clicked on (" + lonlat.lon.toFixed(2) + ", " + lonlat.lat.toFixed(2) + ")",
                maximizable: true,
                collapsible: true,
                map: mapPanel.map,
                anchored: true
            });
            mapPop.doLayout();
            mapPop.show();
        };
    
        var mapCtrl = new OpenLayers.Control.Click({
            trigger: function(evt) {
                var lonlat = mapPanel.map.getLonLatFromViewPortPx(evt.xy);
                lonlat.transform(new OpenLayers.Projection("EPSG:4326"), mapPanel.map.getProjectionObject());
    
                //.transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());
    
                mapAction(lonlat);
            }
        });
        mapPanel.map.addControl(mapCtrl);
        mapCtrl.activate();
    });
    
    // A control to handle user clicks on the map
    OpenLayers.Control.Click = OpenLayers.Class(
        OpenLayers.Control, {
            defaultHandlerOptions: {
                single: true,
                double: false,
                pixelTolerance: 0,
                stopSingle: true
            },
            initialize: function(options) {
                this.handlerOptions = OpenLayers.Util.extend(
                    options && options.handlerOptions || {},
                    this.defaultHandlerOptions
                );
                OpenLayers.Control.prototype.initialize.apply(
                    this, arguments
                );
                this.handler = new OpenLayers.Handler.Click(
                    this,
                    { click: this.trigger },
                    this.handlerOptions
                );
            },
            CLASS_NAME: "OpenLayers.Control.Click"
        }
    );
    
    下面是我正在使用的GeoJSON:

    {
      "type": "FeatureCollection",
      "features": [
        {
          "geometry": {
            "type": "Point",
            "coordinates": [
              -70.3856,
          38.3458
            ]
          },
          "type": "Feature",
          "properties": {
            "name": "Node0",
            "status": "Active",
            "externalGraphic": "img/node2.png",
            "graphicHeight": 75, "graphicWidth": 75
          },
          "id": 100
        },
        {
          "geometry": {
            "type": "Point",
            "coordinates": [
              -70.885810,
          38.344722
            ]
          },
          "type": "Feature",
          "properties": {
            "name": "Node1",
            "status": "Active",
            "externalGraphic": "img/node2.png",
            "graphicHeight": 75, "graphicWidth": 75
          },
          "id": 101
        }
      ]
    }
    

    好的,我是这样处理这个问题的:

  • 我在后端使用嵌入式Jetty Web服务器,但是 不管怎样,我创建了一个servlet来响应GeoJSON格式的数据。 每个特征位置lon/lat在投影之间转换。 (例如EPSG:4326至EPSG:900913)

  • lon/lat投影对话利用了GeoTools Java API。 这篇博文特别有用 () 请注意,如果需要,您将需要经历一段相当多的尝试和错误 您只想包括转换yout所需的JAR 预测。GeoTools规模庞大,功能强大,有许多 罐子

  • 现在,当GeoExt.data.ProtocolProxy加载我的GeoJSON内容时,它已经在OSM兼容的EPSG:900913中了。我本想完全在GeoExt/OpenLayer中处理这个问题,但似乎没有一个简单的方法。我承认GeoExt和OpenLayers没有超级好的参考文档可供遵循

    我会包括我的地理工具代码,但上面的“Arias Prado GIS Ramblings”博客帖子比我做的更好。不过,请再次注意,您必须对罐子进行反复试验。投影编码器是动态加载的,它们又具有来自其他JAR的类依赖关系