Projekcja mapy w OpenLayers

22

Chcę nałożyć niektóre dane, których rzutowanie to WGS-84 na warstwę mapy Google w OpenLayers. Ale po prostu nie mogę zrobić ich we właściwym miejscu. Zrobiłem w następujący sposób:

map = new OpenLayers.Map('map', {           
        numZoomLevels: 20,
        projection: new OpenLayers.Projection("EPSG:900913"),
        displayProjection: new OpenLayers.Projection("EPSG: 4326")
        });
googlelayer = new OpenLayers.Layer.Google("Google street", {sphericalMercator: true});
map.addLayer(googlelayer);
veclayer = new OpenLayers.Layer.Vector("vector", {
                                    projection: map.displayProjection
                                    };
var geojson_format = new OpenLayers.Format.GeoJSON();
veclayer.addFeatures(geojson_format.read(jsonData));

Chociaż mam przypisany veclayerw projekcji 4326, ale nadal jest interpretowany jako 900913, a system koordynacji wyświetlania jest również 900913, chociaż ustawiłem displayProjection na 4326. Jaki błąd popełniam?

ChanDon
źródło

Odpowiedzi:

16

Jestem wielkim fanem „preFeatureInsert” ....

var veclayer = new OpenLayers.Layer.Vector("vector", {
           projection: map.displayProjection,
           preFeatureInsert: function(feature) {
           feature.geometry.transform(projWGS84,proj900913);
           }
        });
CatchingMonkey
źródło
Aha, działa! Dziękuję Ci bardzo. Ale zastanawiam się, co preFeatureInsertoznacza ta właściwość , w każdym razie nie mogę jej znaleźć w oficjalnym dokumencie API ~
ChanDon,
1
Jeśli chodzi o mnie, przekształca projekcje zgodnie z definicją, zanim funkcja zostanie wstawiona ... Ładne i ogólne, i nie ma potrzeby konwersji funkcji itp.
CatchingMonkey
6

Masz miejsce za dwukropkiem. Projection("EPSG: 4326")tak naprawdę Projection("EPSG:4326")nie powinno być wcześniej miejsca 4326.

Vadim
źródło
Haha to naprawdę działa! Mam na myśli projekcję wyświetlacza. Jednak nakładane dane nadal nie są we właściwym miejscu (to samo niewłaściwe miejsce jak poprzednio). Jakieś pomysły?
ChanDon,
2
               map = new OpenLayers.Map('map',
                { numZoomLevels: 19,
                  units: 'm',
                  eventListeners: {"moveend": update_movend},
                  projection: new OpenLayers.Projection("EPSG:900913"),
                  displayProjection: new OpenLayers.Projection("EPSG:4326")

                });

        OpenLayers.Projection.addTransform("EPSG:4326", "EPSG:900913", OpenLayers.Layer.SphericalMercator.projectForward);
        OpenLayers.Projection.addTransform("EPSG:900913", "EPSG:4326", OpenLayers.Layer.SphericalMercator.projectInverse);


        var layerMapnik = new OpenLayers.Layer.OSM.Mapnik("Mapnik");
        var layerTah = new OpenLayers.Layer.OSM.Osmarender("Osmarender");

        var gphy = new OpenLayers.Layer.Google(
            "Google Physical",
            {
                type: google.maps.MapTypeId.TERRAIN
            }
        );
//        gphy = map.projection;

        var gmap = new OpenLayers.Layer.Google(
            "Google Streets",
            {
                numZoomLevels: 20,
            }
        );
        //gmap = map.projection;

        layerMapnik.projection = map.projection;
        layerTah.projection = map.projection;

        vectors = new OpenLayers.Layer.Vector("Vector Layer");

          var help_layer = new OpenLayers.Layer.Vector("Waypoints", {
             projection: map.displayProjection,
             strategies: [new OpenLayers.Strategy.Fixed()],
         });

Zamieściłem mój stary fragment kodu. Pamiętam, że clou jest w projekcjach. addTransform powinien rozwiązać twój problem. (proj4)

Styp
źródło
Dziękuję za pomoc Ale wydaje się, że nie działa
ChanDon,
1

Możesz tam spaść, ponieważ szukasz nieco przesuniętej reprezentacji wektora w Mapach Google, podczas gdy na innych warstwach bazowych jest w porządku, a przekształcenie EPSG: 4326 na EPSG: 900913 lub EPSG: 3857 nie rozwiązuje wszystkiego.

W Mapach Google występuje błąd, który nie ocenia dobrze rozmiaru div podczas inicjowania obiektu OpenLayers Map, jeśli nie jest jeszcze widoczny. Dlatego po wywołaniu transform () i przerysowania () konieczne może być myMapObject.updateSize();powiadomienie Google o rzeczywistej proporcji mapy na ekranie.

Jeśli szukasz ogólnego rozwiązania do przekształcania warstw z jednego rzutu na drugi, możesz użyć tej funkcji:

var myMap = new OpenLayers.Map('mapDiv');

function mapBaseLayerChanged(evtObj) {
  var mapProj, baseProj, map_this, newBase;
  map_this = this;
  newBase = evtObj.layer;
  mapProj = (map_this.projection && map_this.projection instanceof OpenLayers.Projection) ?
            map_this.projection : new OpenLayers.Projection(map_this.projection);
  baseProj = newBase.projection;
  if (!(baseProj.equals(mapProj))) {
     var center, maxExt;
     center = map_this.getCenter().transform(mapProj, baseProj);
     maxExt = newBase.maxExtent;
     map_this.projection = baseProj;
     map_this.maxExtent = maxExt;
     map_this.setCenter(center, map_this.getZoom(), false, true);
     // Transforms all sub-layers
     for (var i = 0; i < map_this.layers.length; i++) {
        if (map_this.layers[i].isBaseLayer == false) {
           map_this.layers[i].addOptions({projection: baseProj}, true);
           // Transforms all features of the vectors
           for (var j = 0; j < map_this.layers[i].features.length; j++) {
              map_this.layers[i].features[j].geometry.transform(mapProj, baseProj);
           }
           map_this.layers[i].redraw();
        }
     }
     //Solves Google's problem (and mine at the same occasion)
     map_this.updateSize();
  }
}
myMap.events.register('changebaselayer', myMap, mapBaseLayerChanged);

Gotowe!

Le Droid
źródło
0

W przypadku Yahoo możesz wypróbować następujące opcje:

baseLayerOptions:{
  sphericalMercator: true,
  maxExtent:new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34)
}
Ivan Malyshev
źródło