I have hexagonal tileset added as a layer to mapbox style though mapbox studio.
Trying to find possibility to reduce layer visible area. For example to show only 100m radius (or square with side equal to 100m) area around map center (current point marker).
Is this possible?
You can create a bounding box and use fitBounds method of the map, for example:
const boundingBox = [
[minX, minY],
[maxX, maxY]
];
map.fitBounds(boundingBox);
More about fitBounds and other examples you can find here.
For creating bounding box you can use Turf.js library.
This code uses buffer and bbox methods to create bounding box with 100m side and given point in the center:
const pointBuffer = turf.buffer(point /* - your point GeoJSON */, 0.1, 'kilometers');
const boundingBox = turf.bbox(pointBuffer);
Related
I can't figure out why the radiusmap layer (first map shown) and the isochronemap layer (second map shown) don't scale correctly when I zoom in and out. The third map, which has the exact same layers, works just fine.
Here's the code for a) creating the circle and polygon layers and then b) adding them to the radiusmap, the isochronemap and finally, the combined map.
var isochrone = L.polygon(isochronedetails, {color: 'red'});
var radius = L.circle([radiuslat, radiuslng], {fillColor: circleStyle.color[0], fillOpacity: circleStyle.opacity[0],radius: radiusmeters});
radius.addTo(radiusmap);
isochrone.addTo(drivetimemap);
radius.addTo(combinedmap);
isochrone.addTo(combinedmap);
The code that is creating / initializing the three maps is here:
radiusmap = L.map('radiusmap').setView([radiuslat, radiuslng],10);
radiusmap.addControl(new L.Control.Fullscreen());
drivetimemap = L.map('drivetimemap').setView([isochronelat, isochronelng], 10);
drivetimemap.addControl(new L.Control.Fullscreen());
combinedmap = L.map('combinedmap').setView([isochronelat, isochronelng], 10);
combinedmap.addControl(new L.Control.Fullscreen());
And here's a gif of what happens on zoom in/out for each map. You'll see that when the zoom happens for the first two maps, the circle or polygon moves away from the original drawing position. But, on the third map, it behaves correctly.
https://screencast-o-matic.com/watch/cYe1VQx6pZ
What am I doing wrong? I just want the first two maps to behave like the third map. :-)
Simply do not add your layers (namely isochrone and radius) to several maps, but create different layers (possibly with same parameters) for each separate map.
Leaflet makes the assumption for simplicity that when a layer is added to a map, it belongs only to that map.
I want to display objects on a map in their exact dimensions.
I have reference data about these objects, containing the length and width of the object in meters, now I need to convert the meters into pixels for the leaflet icon size based on the zoom level.
var meterlength = 50;
var meterwidth = 40;
//convert meters to pixels
var icon = L.divIcon({html:"<svg>..</svg>",iconSize:[xx,yy]});
I found this https://github.com/makinacorpus/Leaflet.GeometryUtil/
GeometryUtils with the length and distance function, but could not get it working.
Any ideas ? Thank you very much !
EDIT:
This answer solved my original problem:
https://gis.stackexchange.com/a/198444
But I'm sacling the icons on map zoom using the "zoomanim" event - unfortunately the map.containerPointToLatLng() Methode applies to the old zoom level not to the new one.
Is there a Workaround ?
If you want your image to represent the object real size, then you should probably better use an L.imageOverlay instead of a marker and trying to adjust its size based on zoom level.
See https://gis.stackexchange.com/questions/171609/resize-divicons-svgs-at-zoom-levels-leaflet
Then you would need to find the appropriate coordinates for your Image Overlay bounds, not pixels.
Now if you really want to change your marker icon size depending on the zoom level, you have several posts on SO and GIS SE that cover this topic.
E.g. Best way to make marker resizable in leaflet
I am using leaflet.js to create few markers and circles. I am using the below given code to draw circles : -
L.circle([ lat, lng ], 1000, {
color : colorCode,
stroke : false,
fillColor : colorCode,
fillOpacity : 0.7
});
Now if I edit this circle on UI and drag this circle vertically downwards, the circle size increases and vice a versa. Similar issue is with calling the above given method with different lat lngs. The same radius (1000) sized circle get plotted with different sizes on map.
My requirement is to place marker with same radius with same size on map everywhere.
I checked L.circleMarker but it takes radius in pixels and also circleMarkers does not scale in zoomin zoomout events. That is why I can't use circleMarkers.
I changed the crs option to 4326 but no success. I am using imageOverlay not tileset. I have created a fiddle.
http://jsfiddle.net/newBee_/88bdrzkr/12/
Try creating a circle on top area then edit and move it downwards. It's size increases. This is what I want to stop. This will resolve the problem of generating circle of same radius via code in different area of map with same size. Please help.
Please suggest.
Edit:
It looks like this is a bug deep into Leaflet 0.x: L.Circle radius computation uses hard-coded Earth projection rather than the specified CRS. Leaflet 1.0 seems to correctly check for the CRS before using the Earth-related computation.
For your case, simply overriding the faulty method seems to fix it, at least visually.
Demo: http://jsfiddle.net/88bdrzkr/13/
The "corrected" method to include in your script:
L.Circle.include({
_getLngRadius: function () {
return this._getLatRadius();
}
});
Regarding iH8's answer, the trick to override L.CRS.Simple.scale is similar to highly zooming (the 256 factor expands the latLng to much further pixels - any high number will do). At high zoom, you are moving your circle along a very short distance, for which the latitude does not change much. So you do not see any visible difference in radius, even though the bug is still there.
Demo of using just higher zoom, no method override at all: http://jsfiddle.net/kau6g8fk/1/
For your need where the circle looks to be more like a visual aid, any of these 3 solutions is enough.
Edit: the CRS is not the issue at all.
Previous message:
If you use Leaflet for indoor mapping, as your jsFiddle suggests (or any flat type map, as opposed to the projection of a sphere like Earth on to a plane), you could simply use L.CRS.Simple
Striked out this faulty solution as pointed out by Ghybs in his answer
Very weird issue, turns out that overloading L.CRS.Simple's scale method to return 256 * Math.pow(2, zoom) fixes this. Here's a fork of your JSFiddle: http://jsfiddle.net/kau6g8fk/ I'm unsure as to the cause of this issue, it would require more research. Will do if i find the time. Found the solution here: http://codepen.io/mike_beweb/pen/BymKGe
The answer below was given before the poster edited his/her question and showed that the used CRS was L.CRS.Simple while i presumed the default CRS. I'll leave it in tact because it might come in handy for some users:
The size change on drag of your L.Circle's is because of your map's default spherical mercator projection (EPSG:3857). Best explained with an image, here's a map with a graticule overlay on every 10 degrees:
Demo on Plunker: Leaflet 0.7.5 EPSG:3857 Spherical
As you move further from the equator every plane becomes higher. Thus your circle automaticly becomes higher the further north/south you drag it. You could use a equirectangular projection (EPSG:4326), in which every plane has the same size regardless of the distance from the equator:
Demo on Plunker: Leaflet 0.7.5 EPSG:4326 Equirectangular
With equirectangle projection you won't have the problem you're having now but you'll have to change your tileset to one with EPSG:4326 projection and those are hard to come by compared to EPSG:3857 tilesets.
If you're not willing or unable to change projection another solution could be to hack around L.CircleMarker and change the radius of your markers depended on current zoomlevel. But that's rather ugly in my opinion.
I'm trying to find out which is the currently centered tile in OpenLayers 3.
I can get the current position as latitude/longitude with map.getView().getCenter(), and the zoom level as map.getView().getZoom().
Am I supposed to convert this to map tiles manually, or does OpenLayers 3 provide a functionality to easily calculate the correct tile x/y indices (the one in which the center lat/lon is located), or am I supposed to calculate this by myself?
you can convert the center position with
center = ol.proj.transform(center, 'EPSG:900913', 'EPSG:4326');
Given a ol3 tile source, you can get the TileGrid by source.getTileGrid().
Then use the getTileCoordForCoordAndResolution method, to get the tile coordinates from a given map coordinate and resolution.
I am totally new to Leaflet JavaScript. Basically I need to program something that:
Allow drawing a bounding box over a map
Get the coordinate of the box
Later on draw the box based on the coordinates
Clear the box
Anya ideas or examples how to do this? Or where to find them?
Thanks
There's a plugin called Leaflet.draw that adds support for drawing and editing vectors and markers onto Leaflet maps. On this link you will find enough information to implement a simple rectangle that will be your bounding box.
With this piece of code you can get the position of the mouse pointer on the map (you just need to create one handler for the mouse down, and the other on mouse up)
map.on('click', onMapClick);
function onMapClick(e) {
alert("You clicked the map at " + e.latlng);
}
3.Draw the box based on coordinates:
var bounds = [[X, Y], [X, Y]];
// create an orange rectangle
var boundingBox = L.rectangle(bounds, {color: "#ff7800", weight: 1});
map.addLayer(boundingBox);
4. Clear the box:
map.removeLayer(boundingBox);