I am trying to center and fit the boundaries of multiple geojson polygon features on my google.maps.Map.
See this non geojson fiddle recreating the effect i'm after.
Is there an easy Google Map API 3 function to do this for geojson data?
See my code below and fiddle here
var map;
window.initMap = function() {
var mapProp = {
center: new google.maps.LatLng(51.8948201,-0.7333298),
zoom: 17,
mapTypeId: 'satellite'
};
map = new google.maps.Map(document.getElementById("map"), mapProp);
map.data.loadGeoJson('https://api.myjson.com/bins/g0tzw');
map.data.setStyle({
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35
});
var bounds = new google.maps.LatLngBounds();
map.fitBounds(bounds);
map.setCenter(bounds.getCenter());
}
I need expert pointers on cleanest and best way approach this.
See working demo of my code above in fiddle.
http://jsfiddle.net/joshmoto/fe2vworc/
I've included my geojson inline so you can see the polygons on the map.
Here is a quick example of how you can get your features bounds. This will just get each feature bounds, extend a LatLngBounds object and then fit the map with these bounds.
var map;
function initialize() {
map = new google.maps.Map(document.getElementById('map-canvas'), {
zoom: 10,
center: {
lat: 0,
lng: 0
}
});
var permits = {
type: "FeatureCollection",
id: "permits",
features: [{
type: "Feature",
properties: {
name: "Alpha Field"
},
geometry: {
type: "Polygon",
coordinates: [
[
[-0.72863, 51.895995],
[-0.730022, 51.896766],
[-0.730754, 51.896524],
[-0.731234, 51.896401],
[-0.731832, 51.896294],
[-0.732345, 51.896219],
[-0.732945, 51.896102],
[-0.732691, 51.895774],
[-0.732618, 51.895531],
[-0.732543, 51.895359],
[-0.73152, 51.894751],
[-0.731037, 51.894488],
[-0.730708, 51.894324],
[-0.72863, 51.895995]
]
]
}
},
{
type: "Feature",
properties: {
name: "Beta Field"
},
geometry: {
type: "Polygon",
coordinates: [
[
[-0.728004, 51.895658],
[-0.72863, 51.895995],
[-0.730708, 51.894324],
[-0.731217, 51.893784],
[-0.730992, 51.893709],
[-0.730793, 51.893567],
[-0.730734, 51.893435],
[-0.730761, 51.89333],
[-0.729696, 51.893244],
[-0.729391, 51.89314],
[-0.729249, 51.893586],
[-0.728991, 51.894152],
[-0.728525, 51.894983],
[-0.728004, 51.895658]
]
]
}
}
]
};
google.maps.event.addListenerOnce(map, 'idle', function() {
// Load GeoJSON.
map.data.addGeoJson(permits);
// Create empty bounds object
var bounds = new google.maps.LatLngBounds();
// Loop through features
map.data.forEach(function(feature) {
var geo = feature.getGeometry();
geo.forEachLatLng(function(LatLng) {
bounds.extend(LatLng);
});
});
map.fitBounds(bounds);
});
}
initialize();
#map-canvas {
height: 150px;
}
<div id="map-canvas"></div>
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk"></script>
Props to #MrUpsidown for providing the working method to fitBounds.
I'm posting this answer to show my final solution based on #MrUpsidown answer using GeoJson data via loadGeoJson()
Here is my readable GeoJson here http://myjson.com/g0tzw
// initiate map
window.initMap = function() {
// permits json
var permits = 'https://api.myjson.com/bins/g0tzw';
// map properties
var mapProp = {
zoom: 17,
mapTypeId: 'satellite'
};
// google map object
var map = new google.maps.Map(document.getElementById("map"), mapProp);
// load GeoJSON.
map.data.loadGeoJson(permits, null, function () {
// create empty bounds object
var bounds = new google.maps.LatLngBounds();
// loop through features
map.data.forEach(function(feature) {
var geo = feature.getGeometry();
geo.forEachLatLng(function(LatLng) {
bounds.extend(LatLng);
});
});
// fit data to bounds
map.fitBounds(bounds);
});
// map data styles
map.data.setStyle({
strokeColor: '#FF0000',
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: '#FF0000',
fillOpacity: 0.35
});
}
I'm calling initMap via...
<script async defer src="https://maps.googleapis.com/maps/api/js?key=<?=$gmap_api?>&callback=initMap"></script>
See working demo here.
http://jsfiddle.net/joshmoto/eg3vj17m/
Related
I have a google map with a set of map markers. I chose to draw the map markers with a function called pinSymbol() - instead of using the default image.
I want to change the color of the pin when it is clicked, but I can't get it to update. With the current code I can change the property of the icon, I can see this with console.log(marker), however it won't update the color on the map.
Question: How do I redraw the icon on click?
This is my code.
// Go through all restaurants and get facebook info,
// then create a marker for each one.
restaurants.forEach(function(restaurant){
getFacebookInfo(restaurant);
}); // end forEach loop
// Get data from Facebook Graph API and create a marker
function getFacebookInfo(restaurant){
$.ajax({
url : '/restaurants/' + restaurant.id,
type : 'GET',
dataType:'json',
success : function(data) {
restaurant.about = data.about;
createMarker(restaurant);
},
error : function(request, error) {
console.log(error);
alert("We're having some trouble getting a restaurant's info from Facebook. " +
"Please check your internet connection and try refreshing the page.")
}
});
}
// Create a marker on the map for a location
function createMarker(restaurant){
var position = restaurant.location;
var infowindow = new google.maps.InfoWindow({
maxWidth: 200
});
restaurant.marker = new google.maps.Marker({
position: position,
map: map,
icon: pinSymbol('#CD212A', '#CD212A'),
name: restaurant.name,
id: restaurant.id,
about: restaurant.about,
animation: google.maps.Animation.DROP
});
// Push the marker to array of markers
markers.push(restaurant.marker);
// Call populateInfoWindow function
populateInfoWindow(restaurant.marker, infowindow);
// Add infowindow as a property to restaurant
// this makes it available for use outside this function.
restaurant.infowindow = infowindow;
This is where I'm stuck:
// Open infowindow when marker is clicked and change color
restaurant.marker.addListener('click', function(){
this.icon = pinSymbol('#EED4D9', '#EED4D9');
console.log(restaurant.marker);
infowindow.open(map, this);
});
}
pinSymbol Function
// Create pin for google map marker
function pinSymbol(color, strokeColor) {
return {
path: 'M 0,0 C -2,-20 -10,-22 -10,-30 A 10,10 0 1,1 10,-30 C 10,-22 2,-20 0,0 z',
fillColor: color,
fillOpacity: 1,
strokeColor: strokeColor,
strokeWeight: 1,
scale: 1,
labelOrigin: new google.maps.Point(0,-29)
};
}
There is no (documented) .icon property of a marker. Don't use it. Use the documented .setIcon method:
// Open infowindow when marker is clicked and change color
restaurant.marker.addListener('click', function() {
this.setIcon(pinSymbol('#EED4D9', '#EED4D9'));
console.log(restaurant.marker);
infowindow.open(map, this);
});
proof of concept fiddle
code snippet:
var geocoder;
var map;
var markers = [];
function initialize() {
map = new google.maps.Map(
document.getElementById("map_canvas"), {
center: new google.maps.LatLng(37.4419, -122.1419),
zoom: 13,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
createMarker({
name: "center",
id: 2,
about: "",
location: {
lat: 37.4419,
lng: -122.1419
}
});
}
google.maps.event.addDomListener(window, "load", initialize);
// Create a marker on the map for a location
function createMarker(restaurant) {
var position = restaurant.location;
var infowindow = new google.maps.InfoWindow({
maxWidth: 200
});
restaurant.marker = new google.maps.Marker({
position: position,
map: map,
icon: pinSymbol('#CD212A', '#CD212A'),
name: restaurant.name,
id: restaurant.id,
about: restaurant.about,
animation: google.maps.Animation.DROP
});
// Push the marker to array of markers
markers.push(restaurant.marker);
// Call populateInfoWindow function
populateInfoWindow(restaurant.marker, infowindow);
// Add infowindow as a property to restaurant
// this makes it available for use outside this function.
restaurant.infowindow = infowindow;
// Open infowindow when marker is clicked and change color
restaurant.marker.addListener('click', function() {
if (this.getIcon().fillColor != "#EED4D9") {
this.setIcon(pinSymbol('#EED4D9', '#EED4D9'));
} else {
this.setIcon(pinSymbol('#CD212A', '#CD212A'));
}
console.log(restaurant.marker);
infowindow.open(map, this);
});
}
// Create pin for google map marker
function pinSymbol(color, strokeColor) {
return {
path: 'M 0,0 C -2,-20 -10,-22 -10,-30 A 10,10 0 1,1 10,-30 C 10,-22 2,-20 0,0 z',
fillColor: color,
fillOpacity: 1,
strokeColor: strokeColor,
strokeWeight: 1,
scale: 1,
labelOrigin: new google.maps.Point(0, -29)
};
}
function populateInfoWindow(marker, infowindow) {
infowindow.setContent("content");
};
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map_canvas"></div>
I draw polygon on my map but i get trouble because it draws a line on center if i formed a square or any shapes.I don't know what makes my polygon draw lines on center.
var map;
var count=0;
var polycolor = '#ED1B24';
var polyarray=[];
function initialize() {
var initial = new google.maps.LatLng(53.199246241276875, -105.76864242553711);
var mapOptions = {
zoom: 16,
center: initial,
zoomControl: true,
zoomControlOptions: {
style: google.maps.ZoomControlStyle.LARGE
},
mapTypeControl: false
};
map = new google.maps.Map(document.getElementById('map_canvas'), mapOptions);
google.maps.event.addListener(map, 'click', function(e) {
polyarray[count]= e.latLng;
addPolygon(polyarray);
count++;
});
}
function addPolygon(path){
var poly = new google.maps.Polygon({
path: path,
strokeColor: polycolor,
strokeOpacity: 1.0,
strokeWeight: 2
});
poly.setMap(map);
}
google.maps.event.addDomListener(window, 'load', initialize);
here is my jsfiddle
my demo
There is not a line down the center, you are drawing a new polygon for each click.
Make the polygon global, and update the path each time you add a point to it:
var poly = new google.maps.Polygon({
strokeColor: polycolor,
strokeOpacity: 1.0,
strokeWeight: 2
});
function addPolygon(path){
poly.setPath(path);
poly.setMap(map);
}
updated fiddle
I'm having a problem setting a variable in ST_DISTANCE to a variable instead of a number. My goal is to sort fusion table entries by distance to the client and only display the closest 3.
(Also, I would like the window to zoom out and encompass those points as well as point to where the client is. Any hints or links to some recourses would be appreciated).
Here is the Google Maps, Fusion Tables, and Geolocation code:
<script type="text/javascript">
(function() {
if(!!navigator.geolocation) {
var map;
var mapOptions = {
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP,
};
navigator.geolocation.getCurrentPosition(function(position) {
var geolocate = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
map.setCenter(geolocate);
});
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions)
layer = new google.maps.FusionTablesLayer({
map: map,
heatmap: { enabled: false },
query: {
select: "col1",
from: "1JaRXQJ_YJch5Ua6cfZCBpaUEKRnd2jIcHVmcODY",
orderBy: 'ST_DISTANCE(col1, LATLNG("geolocate"))',
limit: 3,
where: ""
},
options: {
styleId: 2,
templateId: 2
}
});
} else {
map = new google.maps.Map(document.getElementById('map-canvas'), {
center: new google.maps.LatLng(39.918487877955485, -98.30599773437501),
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
layer = new google.maps.FusionTablesLayer({
map: map,
heatmap: { enabled: false },
query: {
select: "col1",
from: "1JaRXQJ_YJch5Ua6cfZCBpaUEKRnd2jIcHVmcODY",
where: ""
},
options: {
styleId: 2,
templateId: 2
}
});
}
})();
google.maps.event.addDomListener(window, 'load', initialize);
</script>
I know this is messy. I don't know javascript.
I would like to know how to put the variable "geolocate" created by:
navigator.geolocation.getCurrentPosition(function(position) {
var geolocate = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
map.setCenter(geolocate);
});
Into the LATLNG place in:
var layer = new google.maps.FusionTablesLayer({
query: {
select: 'Address',
from: '15UY2pgiz8sRkq37p2TaJd64U7M_2HDVqHT3Quw',
orderBy: 'ST_DISTANCE(Address, LATLNG(37.4,-122.1))',
limit: 3
}
Any help is greatly appreciated.
This is just a basic javascript question ...
Make geolocate global, like var map;
var map;
var geolocate;
Remove var in front of your existing geolocate.
Then remove quotes around your usage of geolocate.
orderBy: 'ST_DISTANCE(col1, LATLNG(' + geolocate + ') )',
I have a map with googlemaps api.
I've added a polygon FusionTable layer.
When I click on a polygon, it shows me the default infowindow with .googft-info-window class.
I want to make changes to that class, or assign other class to these infowindows.
There's a way to do so?
That's my code.
function initialize() {
var mapDiv = document.getElementById('lugar-do-mapa');
map = new google.maps.Map(mapDiv, {
center: new google.maps.LatLng(-12.726084,-51.855469),
zoom: 6,
mapTypeId: google.maps.MapTypeId.ROADMAP,
navigationControl: true,
navigationControlOptions: {
style: google.maps.NavigationControlStyle.SMALL
}
});
fusion = new google.maps.FusionTablesLayer({
query: {
select: 'geometry',
from: 'xxxxXXXxxx'
},
styles: [{
polygonOptions: {
fillColor: "#FFFFFF",
fillOpacity: 0.1,
strokeColor: "#ff4d4d",
strokeWeight: "int"
}
}]
});
fusion.setMap(map);
}
Thank you all,
It works like Dr. Molle said, just placed the class .googft-info-window on my css and changed the parameters...thanks.
I´ve a function that show a polyline on a map, this part is working, now I want to implement a function that hides the polyline, but I can´t find my mistake, thanks in advance.
function cargaMapaCYL(mapa, varControl){
var limite = null;
limite = [
new google.maps.LatLng(42.49956716,-7.019005501),
new google.maps.LatLng(42.49947126,-7.029286373),
new google.maps.LatLng(42.50904062,-7.049299123),
new google.maps.LatLng(42.50722622,-7.069103626),
new google.maps.LatLng(42.50452387,-7.000150672),
new google.maps.LatLng(42.49348015,-6.983058917),
new google.maps.LatLng(42.49843269,-6.971666546),
new google.maps.LatLng(42.51765791,-6.956909023),
new google.maps.LatLng(42.52010069,-6.927429186),
new google.maps.LatLng(42.50992238,-6.914231493),
new google.maps.LatLng(42.50096695,-6.879679821),
new google.maps.LatLng(42.48775868,-6.857775832),
new google.maps.LatLng(43.23907504,-3.293216584)], "#000000", 5);
var contorno= new google.maps.Polyline({
path: limite,
strokeColor: "#000000",
strokeOpacity: 1.0,
strokeWeight: 2
});
if(varControl==true){
contorno.setMap(mapa);
}
if(varControl==false){
contorno.setMap(null);
}
}
You only need to create the Polyline once. Put it into a global var contorno = ... Then you can create a toggle function using the setVisible(boolean) method.
if(contorno.getVisible()){
contorno.setVisible(false);
else{
contorno.setVisible(true);
}
// or
contorno.getVisible() ? contorno.setVisible(false) : contorno.setVisible(true);
Blow is an example which hides the path after 3 seconds.
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
<div id="map"></div>
<script>
// This example creates a 2-pixel-wide red polyline showing the path of William
// Kingsford Smith's first trans-Pacific flight between Oakland, CA, and
// Brisbane, Australia.
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 3,
center: {lat: 0, lng: -180},
mapTypeId: 'terrain'
});
var flightPlanCoordinates = [
{lat: 37.772, lng: -122.214},
{lat: 21.291, lng: -157.821},
{lat: -18.142, lng: 178.431},
{lat: -27.467, lng: 153.027}
];
var flightPath = new google.maps.Polyline({
path: flightPlanCoordinates,
geodesic: true,
strokeColor: '#FF0000',
strokeOpacity: 1.0,
strokeWeight: 2
});
flightPath.setMap(map);
setTimeout(function() {
alert('hide path');
flightPath.setVisible(false);
}, 3000);
}
</script>
<script async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap"></script>
Everytime your function is called, it creates a new polyline. Which is either added to the map or not.
Persumably you want be able to call the function once with true to add the line, then again with false to remove it. At the moment, when you call it a second time, its creates a new line and doesn't add it to the map. It does not touch the original line, already added to the map.
One way is too keep the line in a global variable. Then you can refer to the exact same object between calls.
var contorno = null;
function cargaMapaCYL(mapa, varControl){
if (!contorno) {
var limite = [...], "#000000", 5);
contorno= new google.maps.Polyline({...});
}
if(varControl){
contorno.setMap(mapa);
} else {
contorno.setMap(null);
}
}