I am using google-map-react to render maps in my react app.I am displaying dynamic number of markers on the map.I need to fit the view of map so that it just encloses all the markers.I went through this thread but found it a bit complicated.Can anyone please give me an overview of how this can be done?
It happens that I had to do the exact same thing recently. I found that existing libs were more getting on my way than actually helping so I just went with writing my own component.
In case you decide going the same way - here's how to do what you want:
First - you need to get the bounds object enclosing all your markers. Here we assume that this.state.markers contains an array of google.maps.Marker objects
Your component could have the following method to do that:
getObjectsBounds(){
let objectsBounds = new google.maps.LatLngBounds();
Object.values(this.state.markers).map((marker) => {
let lat = parseFloat(marker.getPosition().lat());
let long = parseFloat(marker.getPosition().lng());
let point = new google.maps.LatLng(lat, long);
objectsBounds.extend(point);
});
return objectsBounds;
}
Now we just use fitBounds on the above funtion's return results. Here we assume that this.map is your gmap, i.e. what google.maps.Map( ... your args ... ) returns.
fitBounds(){
let bounds = this.getObjectsBounds();
this.map.fitBounds(bounds);
}
Related
Hello guys I am trying to create an app that sets the appropriate markers visible when a knockout search is being done.
Basically the app is.
When someone does a search the list that is bellow it, filters the list and makes only the markers that are associated with the filter list visible on the map.
I have created a ko.utils.arrayFilter and I am trying to set only the item.marker.setVisible(true)
My Github link is https://github.com/Aimpotis/map3
Thank you again and much respect to the community it is helping me learn a lot
All you need is to set the visibility of the marker to match whether it is found:
if (!filter) {
// this is new
ko.utils.arrayForEach(self.listLoc(), function (item) {
item.marker.setVisible(true);
});
return self.listLoc();
} else {
return ko.utils.arrayFilter(self.listLoc(), function(item) {
var result = (item.title.toLowerCase().search(filter) >= 0)
item.marker.setVisible(result); // this is a new line
return result;
});
}
Working fiddle.
Note: unless you're supporting particularly old browsers, you can use the Array filter method rather than Knockout's arrayFilter util, and .foreach instead of arrayForEach.
I have been making a script using a fusion table's layer in google maps.
I am using geocoder and get the coordinates of a point that I need.
I put a script that changes the style of a polygon from the fusion table when you click on it, using the google.maps.event.addListener(layer, "click", function(e) {});
I would like to use the same function that I call in the case of a click on the layer, but this time with a click with the coordinates that I got.
I have tried google.maps.event.trigger(map, 'click', {latLng: new google.maps.LatLng(42.701487,26.772308)});
As well as the example here > Google Fusion Table Double Click (dblClick)
I have tried changing map with layer...
I am sorry if my question is quite stupid, but I have tried many options.
P.S. I have seen many post about getting the info from the table, but I do not need that. I want to change the style of the KML element in the selected row, so I do not see it happening by a query.
Here is the model of my script:
function initialize()
{
geocoder = new google.maps.Geocoder();
map = new google.maps.Map(document.getElementById("map_canvas"),myOptions);
layer = new google.maps.FusionTablesLayer({
suppressInfoWindows:true,
map : map,
query : {
select: 'Местоположение',
from: '12ZoroPjIfBR4J-XwM6Rex7LmfhzCDJc9_vyG5SM'
}
});
google.maps.event.addListener(layer, "click", function(e) {
SmeniStilRaionni(layer,e);
marker.setMap(null);
});
}
function SmeniStilRaionni(layer,e)
{
...
}
function showAddress(address)
{
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
var point = results[0].geometry.location;
//IMITATE THE CLICK
}
});
}
In response to geocodezip
This way you hide all the other elements... I do not wish that. It is like if I want to change the border of the selected element. And I do not wish for a new layer.
In the function that I use now I push the style of the options of the layer and then set the option. I use the e from google.maps.event.addListener(layer, "click", function(e)); by inserting e.row['Name'].value inside the where rule.
I would like to ask you if there is any info on the e variable in google.maps.event.addListener(layer, "click", function(e));
I found out how to get the results I wanted:
For my query after I get the point I use this:
var queryText ="SELECT 'Районен съд','Окръжен съд','Апелативен съд','Местоположение' FROM "+FusionTableID+" WHERE ST_INTERSECTS(\'Местоположение\', CIRCLE(LATLNG(" + point.toUrlValue(6) + "),0.5));";
queryText = encodeURIComponent(queryText);
document.getElementById("vij query").innerHTML = queryText;
var query = new google.visualization.Query('http://www.google.com/fusiontables/gvizdata?tq=' + queryText);
And then I get these results:
var rsyd = response.getDataTable().getValue(0,0);
var osyd = response.getDataTable().getValue(0,1);
var apsyd = response.getDataTable().getValue(0,2);
And then, I use the following:
where: "'Районен съд' = '"+rsyd+"'",
Which is the same as:
where: "'Районен съд' = '"+e.row['Районен съд'].value+"'",
in the click function.
This is a working solution for my problem.
But still, I cannot find a way to Imitate a Mouse click.
The issue is this: the data(row) for the layers will be requested via AJAX when you click on a layer.
In theory it's possible to select a geometry(polygon) by a given LatLng, the geometry-library has a method for this: google.maps.geometry.poly.containsLocation().
Unfortunately the FusionTableAPI does not support such queries(ST_CONTAINS), you cannot select a row by supplying a LatLng and selecting the rows where the geometry contains the LatLng.
So what you can do: create a copy of the table that contains the columns needed to select a row(Община...the distinct value, and Местоположение.... the geometry). This copy may be requested via AJAX, but when the FusionTable will not be modified anymore I would suggest to use a hardcoded copy.
What to do now when you want to simulate the click:
Iterate over all rows of the copy, use the mentioned containsLocation()-method to check if the geometry(Местоположение) contains the LatLng and when it does apply the query by using the value of the distinct column Община .
Of course it would take some time to check all the geometries, but the FusionTable is not very large, it should be a possible approach in your case.
Here is a demo: http://jsfiddle.net/doktormolle/sSwj3/
The size of the stored data is approximately 500kb, you should store the data in an external script, so they may be cached.
You may notice that the highligthning of the selected layer will be much faster when triggered via the links, because there will no data be requested via AJAX. When the highlightning of the selected feature is the only thing you need you may ommit the observation of the layer-click completely and observe the map-click instead. Use the returned LatLng to retrieve the selected row from the data and set the style:
Demo: http://jsfiddle.net/doktormolle/swdX8/
I am working on integrating Google Maps into a web application and I have a question of possibility.
I am using ASP .Net 4.0 as the basis for the code, but i suspect i will have to use JavaScript to achieve most of this, which is. Basically I want to display a bunch of markers on a map from Lat Long locations i have stored in a database, then have the user be able to draw a box on the map with the mouse, then get back the lat long of the four corners of the box.
If anyone knows how i could do this this would be of great help to me!
Thanks
The complexity of the Google Maps API has kept me scared for years. Recently I stumbled upon a jQuery plugin called GMap3 that does a lot of the heavy lifting for you.
I would suggest that after initializing and all that, you print a Javascript block from your .NET code, with something like this:
var markersFromDatabase = [
[60.164967,24.94758],
[59.956495, 10.764599]
//etc. This array should be printed from your serverside code
];
var markersToBeAdded = [];
jQuery.each(markersFromDatabase, function(indexOfItem, valueOfItem){
markersToBeAdded.push({
lat:valueOfItem[0],
lng:valueOfItem[1],
options: {
draggable: false,
icon: "img/your_awesome_icon.png",
title: "This is an icon from my database!"
}
});
});
jQuery("#map_canvas").gmap3(
{ action: 'addMarkers',
markers: markersToBeAdded
}
);
Edit: I realize now that I only answered half of your question. I'm afraid I have no apparent answer to the selection box. I suspect that you can use addRectangle or, in a worst case scenario, addFixPanel that lets you add a transparent <div> over your map canvas (and then trigger mouse events for that).
Here is one way to do it with Google Maps API 3's overlay editable feature.
Google Maps Overlay Editable
If your question is "How to select multiple markers with a rectangle", you can do something like this:
var markers = []; // This array must be filled with your data
var rectangles = [];
var triggeredMarkers = [];
google.maps.event.addListener(drawingManager, 'rectanglecomplete', updateSelection);
function updateSelection(rectangle){
var lat_max = rectangle.getBounds().getNorthEast().lat();
var lat_min = rectangle.getBounds().getSouthWest().lat();
var lng_max = rectangle.getBounds().getNorthEast().lng();
var lng_min = rectangle.getBounds().getSouthWest().lng();
rectangles.push(rectangle);
for(var i=0;i<markers.length;i++){
if((lat_min < markers[i].getPosition().lat() ? (markers[i].getPosition().lat() < lat_max ? true:false):false)
&& (lng_min < markers[i].getPosition().lng() ? (markers[i].getPosition().lng() < lng_max ? true:false):false)){
triggeredMarkers.push(markers[i]);
}
}
}
The rectangles array is used to hold rectangles in order to be able to erase them later.
But if you just want a simple function that handle Polygons, there is this one that really can be helpful for you. It can be used like this:
var markers = [];
var polygones = [];
var triggeredMarkers = [];
google.maps.event.addListener(drawingManager, 'polygoncomplete', updateSelection);
function updateSelection(polygon){
polygones.push(polygon);
for(var i=0;i<markers.length;i++){
if(google.maps.geometry.poly.containsLocation(markers[i].getPosition(),polygon)){
triggeredMarkers.push(markers[i]);
}
}
}
For rectangles and circles there's this answer that can help you.
I have tried to draw Polygon using Drawing Manager and send the Polygon Coordinates to PHP script(to store in Database).
1)i have coded editable option as 'true' for polygon. But i am not to
edit the polygon.I am not to find what i did wrong?
2)Also i try to get
Polygon paths using getPaths method..it is returned as array..How do i
check this coordinates are correct. If i put in alert in displays as
'Object[] Object'.Please help me to solve these problems.
You need to set the drawing mode to true (to enable map interactions). the following code will do the trick :)
google.maps.event.addListener(drawingManager, 'polygoncomplete', function(polygon) {
drawingManager.setDrawingMode(null);
});
with regards to the 2nd part im currently working on that now. use console.log instead of alert.
For the path:
var thisPath=polygon.getPath();
for(i=0;i<thisPath.length;i++){
var latlng=thisPath.getAt(i);
pathString= pathString+', '+ latlng.lat()+' - '+ latlng.lng()+'\n'
}
alert (pathString);
For part 2, sharingStuff code would work, I preferred for the path to be a json object,
vertices = this.polygon.getPath();
var points = [];
// Iterate over the vertices.
if(this.polygon.getMap() == null){
return false;
}
for (var i =0; i < vertices.length; i++) {
var xy = vertices.getAt(i);
points.push(xy.lat() +"," + xy.lng());
}
return JSON.stringify({points: points});
either method is fine, just thought I'd give you another option. :)
I am using Google Map v2 and I only want map view and nothing more. I also would like to get rid of the zoom in and out buttons.
If anyone knows what I need to add to the following that would be great.
function stores()
{
$('#storelist ul#stores').html("");
fetch(203,"task=location&location=vic");
map = new GMap2(document.getElementById("map_canvas"));
map.setCenter(new GLatLng(-37.810013, 144.962683), 8);
map.setUIToDefault();
yellowIcon.image = "http://gmaps-samples.googlecode.com/svn/trunk/markers/orange/blank.png";
markerOptions = { icon:yellowIcon };
}
Remove map.setUIToDefault(). It adds the default look and feel to the Map.
(Reference docs: http://code.google.com/apis/maps/documentation/javascript/v2/reference.html#GMap2.setUIToDefault)
If you want, you can also customise how the map can be interacted with. For example map.disableDoubleClickZoom() or map.disableDragging(). See the reference above for details.