简体   繁体   English

Openlayers使用OSM样式贴图和GeoJSON矢量图层进行投影

[英]Openlayers projection with OSM style maps and a GeoJSON vector layer

Note: I know there's another question similar to this but it hasn't been answered and I need to know how mixed projections can be dealt with with GeoJSON and OSM. 注意:我知道还有另一个与此类似的问题,但尚未得到解答,我需要知道如何使用GeoJSON和OSM处理混合投影。

I'm so confused. 我很困惑。 I was using the OSMDroid API on Android for mapping and wanted to replicate it using OpenLayers and GeoExt, but I've got a projection problem with including GeoJSON nodes and action events. 我在Android上使用OSMDroid API进行映射,并希望使用OpenLayers和GeoExt复制它,但我有一个包含GeoJSON节点和动作事件的投影问题。

My tile set is OSM based, and is hosted on the same Web server as this HTML/JS. 我的tile集是基于OSM的,并且托管在与此HTML / JS相同的Web服务器上。 See it all below. 请在下面查看。 I realize my boundaries aren't working, and my projections might be completely wrong. 我意识到我的界限不起作用,我的预测可能完全错误。 I've been testing different combinations. 我一直在测试不同的组合。

The problem is my map displays correctly and is centered fine. 问题是我的地图显示正确并且居中。 However: 然而:

  1. My GeoJSON feature nodes are way off the map. 我的GeoJSON特征节点远离地图。 They're in a different projection long/lat, but I don't know how to set or convert GeoJSON long/lat to the current map projection. 它们处于不同的投影长/纬度,但我不知道如何将GeoJSON long / lat设置或转换为当前地图投影。

  2. My mapCtrl doesn't work. 我的mapCtrl不起作用。 When I click it the lonlat is another projection (the OSM projection coords) and I can't seem to convert them) 当我点击它时,lonlat是另一个投影(OSM投影坐标),我似乎无法转换它们)

  3. Any tips on how extent/bounds actually work would be greatly appreciated 关于范围/界限如何实际工作的任何提示将不胜感激

Can someone please help with a bit of projection advice? 有人可以请一点投射建议吗? Sigh... I'm not patient enough for this. 叹了口气......我对此并不耐心。

在此输入图像描述

Here's my full JS, as is: 这是我的完整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"
    }
);

Here's the GeoJSON I'm using: 这是我正在使用的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
    }
  ]
}

Ok, here's how I dealt with the issue: 好的,这是我处理这个问题的方式:

  1. I'm using the embedded the Jetty Web server in my back-end, but regardless, I created a servlet to respond with GeoJSON format data. 我在我的后端使用嵌入式Jetty Web服务器,但无论如何,我创建了一个servlet来响应GeoJSON格式数据。 Each Feature location lon/lat is converted between projections. 每个要素位置lon / lat在投影之间转换。 (eg EPSG:4326 to EPSG:900913) (例如EPSG:4326到EPSG:900913)

  2. The lon/lat projection conversation leveraged the GeoTools Java API. lon / lat投影对话利用了GeoTools Java API。 This blog post was particularly helpful ( http://ariasprado.name/2012/08/13/quick-and-dirty-coordinate-transforming-using-geotools.html ) Note that you'll need to go through a fair bit of trial and error if you only want to include the jars required for converting yout projections. 这篇博文特别有用( http://ariasprado.name/2012/08/13/quick-and-dirty-coordinate-transforming-using-geotools.html )请注意,你需要经历一段时间的如果您只想包含转换预测所需的罐子,请尝试反复试验。 GeoTools is large, does a lot, and has a number of jars. GeoTools很大,做了很多,并且有很多罐子。

Now when the GeoExt.data.ProtocolProxy loads my GeoJSON content it's already in OSM compatible EPSG:900913. 现在,当GeoExt.data.ProtocolProxy加载我的GeoJSON内容时,它已经在OSM兼容的EPSG:900913中。 I would have liked to deal with this entirely in GeoExt/OpenLayer, but there doesn't appear to be an easy way. 我本来希望在GeoExt / OpenLayer中完全处理这个问题,但似乎没有一个简单的方法。 I will acknowledge that GeoExt and OpenLayers don't have super great reference documentation to follow. 我将承认GeoExt和OpenLayers没有超级好的参考文档可供遵循。

I'd include my GeoTools code but "Arias Prado GIS Ramblings" blog post above does a better job than I could. 我将包含我的GeoTools代码,但上面的“Arias Prado GIS Ramblings”博客文章比我做得更好。 Again though, note that you'll have to trial and error the jars. 但是,请注意,您必须对罐子进行试验和错误。 Projection encoders are loaded dynamically, and they in turn have class dependencies from other jars. 投影编码器是动态加载的,而它们又具有来自其他jar的类依赖关系。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM