Using NodeJS to drop datapoints on a map via Leaflet.
Current issue:
When I scroll out, I can't get the map region to be locked to one Earth. That is, when I scroll out all the way, I end up with 5 copies of Earth, unique from each other. I want the map to be locked to one frame of the Earth.
Methods tried:
I've tried using Map.setView, setZoom, fitBounds, setMaxBounds/maxBounds (which was successful in locking panning, but not scrolling). As far as I can tell I've been using these correctly/in the correct places, but still to no avail.
Figured it out Eugen!
Needs to be set in the initializeLeaflet method. Code added to fix it seen at the bottom of this block.
initializeLeaflet() {
const mapRoot = this.template.querySelector('.map-root');
this.map = L.map(mapRoot);
this.map.fitWorld();
L.control.scale().addTo(this.map);
this.map.setMinZoom(2);
this.map.setMaxZoom(8);
}
Related
I am working on a Google Streetview indoor application using the Google Maps JS API. I am using panorama pictures that are available on Google Streetview. I sometimes want to programatically change the position, for instance when somebody clicks on a position in a small map. However, when I call panorama.getPosition() I automatically get redirected to a different position. I can actually see the position_changed event being triggered twice.
I already sort of found the cause of this issue. It has something to do with the starting/entrance positions Google maps uses for Streetview Indoor.
The two orange circles depict the two possible starting/entrance points into the building. When dropping the pegman over these circles you will enter the building in Streetview Indoor.
It looks like when these starting points exist, the Google Maps API does not let you programatically set the position to some position other then any of the starting points. It will always redirect you to one of the starting points. This is obviously not what I want.
//The starting/entrance position is lat: 52.089988, lng: 5.178041
//The position I want to go to
var goToPosition = {lat: 52.0898852, lng: 5.1780344};
//Position changed EventListener
google.maps.event.addListener(panorama, 'position_changed', function() {
var newPosition = panorama.getPosition();
console.log('changed position to:', newPosition.lat(), newPosition.lng());
});
//Calling setPosition with goToPosition
panorama.setPosition(goToPosition);
//Will result in two console.logs directly printed after another:
changed position to: 52.0898852 5.1780344 //goToPosition
changed position to: 52.089988 5.178041 //starting position
The console.logs show that it looks like the position is being changed twice directly after each other, ending the position at the starting position.
I'm wondering if any body else has encountered this problem and if there is a known workaround for this. I am in contact with the photographer that uploaded the panorama pictures to Google. Maybe there's something in the way these pictures are uploaded to Google and configured. I wonder if this can even be fixed in my application code, or if it's an API problem or even expected behavior.
Thanks!
I found the solution for my problem, partly thanks to #LilDevil's answer.
Each panorama for a position has a panorama ID. If you know the panorama ID in advance, it can be used to move to that position using setPano().
I store panorama ID together with the lat,lng of a position. When clicking on the map I calculate the known position that is nearest to the clicked position. I can then look up the panorama ID that belongs to this position and use it to move to that panorama using setPano().
This doesn't seem to be a very clean way to solve the problem, because the panorama ID might change over time (for instance when new panorama pictures are uploaded to Google Streetview). However, I couldn't find anything in the documentation that says this method shouldn't be used. The documentation says that this method should be used when dealing with custom panorama pictures, which is not the case in my situation. Also, in this specific situation we are in control of when new panorama pictures will be uploaded (because it's for Google Indoor) so I can change the stored panorama ID's if that happens.
You can't just set the panorama to any coords. You need to use getPanorama() with your start coords and a radius, to find the coords to the nearest panorama, then set the pano to those coords. Some examples on https://developers.google.com/maps/documentation/javascript/streetview?hl=en
I am coding in JavaScript using the Google Maps API, and I was curious if there was a way to set the priority of what polygon array info window is shown when I click on an area. I have two polygons that are overlapping, and I need to control which info bubble appears when you click on the overlapped area. Thank you!
The click will be triggered on the most top Polygon.
The order of the polygons usually depends on the order in which they have been added to the map(when the map-property has been set) or by setting a custom zIndex-property.
So when you want to define a priority you must define the zIndex for the Polygons.
When you want to be able to click on each polygon(and each part of each polygon) there is a simple approach:
Observe the mouseover of the polygons and set the zIndex of the hovered polygon to a value higher than the zIndex of the other polygons. This will bring the polygon into front and you now may also click on the previously covered area.
You may implement this by extending the polygon-prototype:
(function(){
var a=z=0;
google.maps.Polygon_=function(opts){
this.setValues(opts)
google.maps.event.addListener(this,'mouseover',function(){
this.set('zIndex',++z);
});
google.maps.event.addListener(this,'rightclick',function(){
this.set('zIndex',--a);
});
};
google.maps.Polygon_.prototype = google.maps.Polygon.prototype;
google.maps.Polygon = google.maps.Polygon_;}
)();
Demo: http://jsfiddle.net/doktormolle/wznd5nsy/
(Use rightclick to send a polygon to back, e.g. when it completely covers another polygon).
I want to split my map into tiles/territories. So i've prepared another layer showing squares. But this layer is full of .png image files so there is no data/object for this squares.
I've also tried to draw squares with leaflet's geometry objects. But it causing performance issues, there is times to show 500+ squares.
If you develop something like that what method would you prefer? UTFGrid? GeoJSON/Geometry? Or maybe any other better solution?
UPDATE:
Actually i don't want to get data belongs to square's territory i just want to change the square's color somehow i mean somehow i want to highlight that area maybe i can create a rectangle on the fly when user mouseover.
And im trying avoid to use UTFGrid for just highlighting. But I want to ensure the UTFGrid is the only way or not.
This sounds like the exact reason that UTFGrid was created! This site links to the tutorial that I used when learning UTFGrid, and it is solid.
Updated after your update:
MarkerCluster might have the look/feel you are going after, they basically paint a polygon onto the map layer. You can check the source here, and here's a relevant snippet:
_showCoverage: function (e) {
var map = this._map;
if (this._inZoomAnimation) {
return;
}
if (this._shownPolygon) {
map.removeLayer(this._shownPolygon);
}
if (e.layer.getChildCount() > 2 && e.layer !== this._spiderfied) {
this._shownPolygon = new L.Polygon(e.layer.getConvexHull(), this.options.polygonOptions);
map.addLayer(this._shownPolygon);
}
},
I would like to be able to fitBounds to a feature when you click on it, but when it zooms in I'd like it to take into account a control layer that will appear once zoomed in, and zoom in but just about 150px to the left. Currently I can accomplish this with the following code, but unfortunately it's not a smooth zoom because my current method will zoom using fitBounds and then once zoomed it uses panBy to pan 150px to the left. This wouldn't be so bad if the panning was smooth, perhaps maybe after a 250ms wait. Ideally I would like to be able to do some math on the bounds passed to the fitBounds method to simply account for the 150px shift to the left.
Here is an example of what I currently have working.
Here is a simplified version of the code I'm using: (you may click here for a fully working version with all of the source code)
when you click
function clickFeature(e) {
var layer = e.target;
map.fitBounds(layer.getBounds());
}
map on zoomEnd:
map.on({
zoomend: function() {
map.panBy([150, 0]);
}
});
So, I've achieved the desired function, but it's just not smooth.
Is there a way to just do some math on the bounds that we're getting for the clicked feature so that when we zoom we zoom into an already modified coordinate, thus eliminating the two-step animation process?
First of all, you can control the animation using pan options. This could help you make the transition smoother.
You can see those here.
Second, you can calculate the offset that you need by using the conversion functions. These can be seen here.
For example, you could do something like (off the top of my head) use getBoundsZoom for the map object on the polygon bounds to figure out your future zoom, then use that zoom in the project function with the polygon and create a new LatLngBound from the polygon bound that is slightly offset.
Hope this helps!
I had this same issue, and if was easier than I had thought!
You can set padding on the fitBounds method (and all the pan/zoom methods for that matter)
http://leafletjs.com/reference.html#map-fitboundsoptions
so:
map.fitBounds(layer.getBounds(),{paddingBottomRight:[150,0]});
How can I set it up so when a user clicks the submit button, the map will resize itself to fit directions as it is on yelp maps when finding directions?
Thanks
Well, without much information in your question, just add a style modification in your map direction handler. In it's simplest form: But without knowing more about your particular setup, I can't do much more.
HTML:
<FORM onSubmit="findDirections()">
JavaScript:
function findDirections() {
// Change map width
document.getElementsById("directions_map").style.width = "600px";
// Do google maps lookup, etc
}
Do you mean how to set center and zoom of map to have direction fit in such a view? If so, you can obtain points of this direction, add them to create LatLngBounds (using the extend method) and use Map.fitBounds with prepared bounds as parameter.