leaflet circle drawing / editing issue - javascript

I am working on leaflet for the very first time and facing the issue with drawing circles and editing (changing location of circle).
The problems I am facing are :-
Editing (moving) circle from one location to another changes its radius.
Note: Pls try to create circle on top of map in given fiddle and then move it to the bottom by clicking edit button.
If I create circle on top section of map it works fine. But If I create circle on bottom of map it only prints a single DOT on map.
I checked few examples and it works fine everywhere.
Here is the working example where circle creation and moving circle is completely fine.
I am not using the geographic map like google maps. I am using and static image as it is my project requirement.
Here is the fiddle of my code.
Just using following code to enable drawing circle :
enabled : this.options.circle,
handler : new L.Draw.Circle(map,this.options.circle),
title : L.drawLocal.draw.toolbar.buttons.circle

What you're seeing is distortion in distance inherent in the mercator projection (and the Google Mercator projection based off it that is inherent to most online maps). Because your map starts at zoom 1, dragging the circle marker north/south will cause a lot of distortion.
So, rather than georeference your image to a global bounding box, try georeferencing it to something much smaller. In your case, your are adding your image overlay relative to the maxZoom, so by increasing maxZoom, your image will be overlayed over a smaller area of the globe, and you will see less (or no) distortions across latitudes.
I changed the maxZoom from 4 to 14, and the result looked like it worked well: fiddle here:
var w = 553, h = 329, url = 'https://kathleenmillar.files.wordpress.com/2012/10/picture2.png';
var map = L.map('map', {
minZoom : 10,
maxZoom : 14,
center : [ w / 2, h / 2 ],
zoom : 11,
crs : L.CRS.Simple
});
// calculate the edges of the image, in coordinate space
var southWest = map.unproject([ 0, h ], map.getMaxZoom() - 3);
var northEast = map.unproject([ w, 0 ], map.getMaxZoom() - 3);
var bounds = new L.LatLngBounds(southWest, northEast);

Related

Animate polygon point on a circle with Paper.js

I need to animate a point (called segment in Paper.js) of a polygon, rotating it on a circle with origin in the original polygon point. See the image below:
I'm trying to do it with this code:
// Draw the polygon
var polygon = new Path.RegularPolygon({
center: [100, 100],
sides: 8,
radius: 80,
});
// Animate
view.onFrame = function (event) {
var offset = new Point(Math.cos(event.time*2), Math.sin(event.time*2));
polygon.firstSegment.point = polygon.firstSegment.point.add(offset);
};
but I get two problems:
the origin of the circle is wrong
after some times of animation it starts to rotate in some strange and (apparently) randomly ways. It seems that it changes the circle origin
Here the whole code to see it in action:
https://codepen.io/anon/pen/xezQpb
Someone can helps? Thanks
The problem is that at each frame you refer to the position of the first segment which has moved a bit during the previous frame, so the offset sums up.
Instead, just record the center at the beginning and offset from that point :
var center = polygon.firstSegment.point.clone();
[...]
polygon.firstSegment.point = center.add(offset);
https://codepen.io/anon/pen/YMjWBZ

Leaflet geoJson layers hidden outside viewport

I have a leaflet map with a few layers on it.
Whenever layers are not in the viewport, they are hidden untill panning has completed:
Regular view with layers:
Panning right, to show layers outside viewport:
Panning stopped:
As illustrated above, the layers will first become visible once panning has stopped and mouse(finger) released.
I have tried the following, which didn't work
var map = L.map('map',{ bounceAtZoomLimits: false, removeOutsideVisibleBounds: false}).setView([40, 0], 2);
L.geoJson(mapData).addTo(map);
Seems the solution was right in front of me
Adding the following will render the entire map:
var map = new L.Map('map');
map.getRenderer(map).options.padding = 100;
Solution found here

How to reduce visible part (or mask) of mapbox style layer?

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);

Offset a LatLngBounds in a Leaflet map

I have a map that fills the screen, and a horizontal overlay of non-map content displayed in the bottom portion of the screen. I want to display a polyline on the map so that it as large as possible within the map view but not hidden below the overlaid content.
Below is what I am trying and it nearly works but gives different results depending on the zoom / position of the map's current view. I need something independent of the current view of the map.
// `map` is the leaflet map
// `polyline` is a leaflet polyline
function fitBounds (latLngBounds, offsetY) { // offsetY in pixels
var zoom, southeast, southeastOffset, newBounds;
if (offsetY) {
zoom = map.getBoundsZoom(latLngBounds);
southeast = map.project(latLngBounds.getSouthEast(), zoom);
southeastOffset = new L.Point(southeast.x, southeast.y + offsetY);
newBounds = latLngBounds.extend(map.unproject(southeastOffset, zoom));
}
map.fitBounds(newBounds || latLngBounds);
}
var contentHeight = 350;
// this will be calculated and is the distance from the top of the
// overlaid content to the bottom of the map
fitBounds(polyline.getBounds(), contentHeight);
The map.getBoundsZoom(latLngBounds) and project/unproject seem to return different values when the map is panned or zoomed differently. I understood from the docs that they'd be independent of the current map view.
Am I using the methods wrong, or is there a different strategy to achieve what I need? Thanks.
getBoundsZoom is dependent on the current map view port size. Therefore if you test with different sizes (e.g. your map container fills the whole page width and you have varying browser window width, possibly because of the console), the results will be different.
If you are sure the map container size has not changed, and you can reproduce the problem on JSBin / Plunker / JSFiddle, then there might be a bug in Leaflet; feel free to report it in the issue tracker.

Google Maps fit markers in custom bounds

I have a Google Maps canvas that stretches the full width and height of the page. Overlaid on top of it is a header which is fixed height (100 pixels) and a sidebar which is a responsive width (20% + 5% margin).
Fiddle for demonstration: http://jsfiddle.net/L9yjvdLv/1/
The problem I'm facing is making sure that all the markers on the map are visible.
I tried playing around with fitBounds, but the problem is that the map doesn't take into account the overlaid elements, meaning markers will be behind the sidebar or header elements, or very close to them.
How do I zoom and center the map so that all markers are visible in the "usable" area of the map?
You will need to use the map projection and fromLatLngToPoint to translate between coordinates and points to be able to take into account your different overlay elements.
For a full explanation, please check this answer.
function fromLatLngToPoint(latLng) {
var scale = Math.pow(2, map.getZoom());
var nw = new google.maps.LatLng(map.getBounds().getNorthEast().lat(), map.getBounds().getSouthWest().lng());
var worldCoordinateNW = map.getProjection().fromLatLngToPoint(nw);
var worldCoordinate = map.getProjection().fromLatLngToPoint(latLng);
return new google.maps.Point(Math.floor((worldCoordinate.x - worldCoordinateNW.x) * scale), Math.floor((worldCoordinate.y - worldCoordinateNW.y) * scale));
}
My example only has a left sidebar overlay but you should be able to adapt the functions to your needs.
JSFiddle demo
Hope this helps.

Categories

Resources