问题
I'm building a story map with Leaflet using a large image sliced into tiles rather than 'real world' map data. I'm using this plugin: https://commenthol.github.io/leaflet-rastercoords/ and this repo: https://github.com/jackdougherty/leaflet-storymap
Loading my GeoJSON data and unprojecting the coordinates correctly plots them on my image map:
$.getJSON('map.geojson', function(data) {
var geojson = L.geoJson(data, {
// correctly map the geojson coordinates on the image
coordsToLatLng: function (coords) {
return rc.unproject(coords)
},
But when I get to onEachFeature, I hit the wall with map.flyTo(), which is calling geometry.coordinates from my JSON file, but not unprojecting them so flyTo() is interpreting them as geospatial coordinates way off the map:
map.flyTo([feature.geometry.coordinates[1], feature.geometry.coordinates[0] ], feature.properties['zoom']);
I tried passing the unprojected coordinates to variables and then to map.flyTo() and variations on nesting functions, such as map.flyTo.unproject(..., but no luck.
How do I pass my raster coordinates to flyTo()?
I'm not only new to Leaflet, but new to JavaScript. I hacked my way this far, but I'm stumped. I'm sure the solution is obvious. Any help is greatly appreciated.
回答1:
In your case you would probably just need to use rc.unproject
to convert your coordinates into LatLng that you can pass to flyTo
:
map.flyTo(
rc.unproject(feature.geometry.coordinates),
feature.properties['zoom']
);
That being said, I must admit I do not exactly see the point of using leaflet-rastercoords plugin, since you can easily do the same by following the Leaflet tutorial "Non-geographical maps".
var yx = L.latLng;
var xy = function(x, y) {
if (L.Util.isArray(x)) { // When doing xy([x, y]);
return yx(x[1], x[0]);
}
return yx(y, x); // When doing xy(x, y);
};
With this, whenever you want to convert your "raster" coordinates into something usable by Leaflet, you would just use xy(x, y)
with x
being your horizontal value, and y
your vertical one.
The added benefit is that many other things will become easily compatible.
Since you use tiles instead of a single image (that is stretched with ImageOverlay
in the tutorial in order to fit the coordinates), you should modify the CRS transformation, so that at zoom 0, your tile 0/0/0
fits your entire coordinates. See also Leaflet custom coordinates on image
I.e. in the case of leaflet-rastercoords example:
- Original raster image size: 3831 px width x 3101 px height
- Tiles size: 256 x 256 px
- Vertical "raster" coordinates are increasing while going down (whereas in the Leaflet tutorial, they increase going up, like latitude).
- Tile
0/0/0
actually covers more than the original image, as if the latter were 4096 x 4096 px (the rest is filled with white)
Determination of the new CRS:
- Tile 0/0/0 should cover coordinates from top-left [0, 0] to bottom-right [4096, 4096] (i.e. 256 * 2^4 = 256 * 16 = 4096) => transformation coefficients
a
andc
should be1/16
- No offset needed => offsets
b
andd
are0
- No reversion of
y
vertical coordinate =>c
is positive
Therefore the new CRS to be used would be:
L.CRS.MySimple = L.extend({}, L.CRS.Simple, {
// coefficients: a b c d
transformation: new L.Transformation(1 / 16, 0, 1 / 16, 0)
});
Now your flyTo
is very similar, but many other things are also compatible:
map.flyTo(
xy(feature.geometry.coordinates),
feature.properties['zoom']
);
Demo adapted from leaflet-rastercoords example, and using an extra plugin to demonstrate compatibility: https://plnkr.co/edit/Gvei5I0S9yEo6fCYXPuy?p=preview
来源:https://stackoverflow.com/questions/44054833/how-to-use-leaflet-flyto-with-unproject-and-geojson-data-on-a-large-raster-i