I have been struggling how to solve a problem with how google maps renders a KML polygon. In Good Earth, it renders the polygon correctly like this:
But in Google maps, when I add this to the map, it incorrectly looks like this:
Surprisingly, this is made of 32 points which go across Africa, NOT the Pacific Ocean!
Why in the world is this being rendered inversely when I specifically indicate the points? Is it just simply ignoring them?
I created a JSFiddle for this here: https://jsfiddle.net/qsz5ec5y/1/
The KML file is here: https://dl.dropboxusercontent.com/u/27946381/testzone.kml
Any ideas as to why this is happening?
Thanks!
I would say the Google Maps KML parser is broken.
Your bug report on the issues list
You KML has a well defined polygon with several points on each side (which should be more than enough to tell it which way the polygon goes):
142.207023447954498,-24.785157829137347 112.016594491497187,-24.785157829137347 81.826165535039934,-24.785157829137347 51.635736578582652,-24.785157829137347 21.44530762212537,-24.785157829137347 -8.745121334331884,-24.785157829137347 -38.935550290789166,-24.785157829137347 -69.125979247246434,-24.785157829137347 -99.316408203703702,-24.785157829137347 -99.316408203703702,-19.291993899650947 -99.316408203703702,-13.798829970164547 -99.316408203703702,-8.305666040678148 -99.316408203703702,-2.812502111191748 -99.316408203703702,2.680661818294652 -99.316408203703702,8.173825747781052 -99.316408203703702,13.666989677267452 -99.316408203703702,19.160153606753852 -69.125979247246434,19.160153606753852 -38.935550290789166,19.160153606753852 -8.745121334331884,19.160153606753852 21.44530762212537,19.160153606753852 51.635736578582652,19.160153606753852 81.826165535039934,19.160153606753852 112.016594491497187,19.160153606753852 142.207023447954498,19.160153606753852 142.207023447954498,13.666989677267452 142.207023447954498,8.173825747781052 142.207023447954498,2.680661818294652 142.207023447954498,-2.812502111191748 142.207023447954498,-8.305666040678148 142.207023447954498,-13.798829970164547 142.207023447954498,-19.291993899650947 142.207023447954498,-24.785157829137347
fiddle showing points above
Your KML also works in geoxml3 (which renders it as native google.maps.Polygon objects) (if you load the KmlLayer you can see the issue)
code snippet showing your rectangle rendered both as KML and a "normal" google.maps.Polygon:
var geocoder;
var map;
var ctaLayer;
var poly;
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
});
var bounds = new google.maps.LatLngBounds();
var path = [];
var coordsStr = kmlCoords.split(" ");
for (var i = 0; i < coordsStr.length; i++) {
var coords = coordsStr[i].split(',');
var latLng = new google.maps.LatLng(coords[1], coords[0]);
path.push(latLng);
bounds.extend(latLng);
var marker = new google.maps.Marker({
position: latLng,
map: map,
title: latLng.toUrlValue(6)
});
}
map.fitBounds(bounds);
poly = new google.maps.Polygon({
path: path,
map: map
});
ctaLayer = new google.maps.KmlLayer({
url: 'https://dl.dropboxusercontent.com/u/27946381/testzone.kml'
});
ctaLayer.setMap(map);
}
google.maps.event.addDomListener(window, "load", initialize);
function toggleKml() {
if (ctaLayer.getMap() == null) {
ctaLayer.setMap(map);
} else {
ctaLayer.setMap(null);
}
}
function togglePolygon() {
if (poly.getMap() == null) {
poly.setMap(map);
} else {
poly.setMap(null);
}
}
var kmlCoords = "142.207023447954498,-24.785157829137347 112.016594491497187,-24.785157829137347 81.826165535039934,-24.785157829137347 51.635736578582652,-24.785157829137347 21.44530762212537,-24.785157829137347 -8.745121334331884,-24.785157829137347 -38.935550290789166,-24.785157829137347 -69.125979247246434,-24.785157829137347 -99.316408203703702,-24.785157829137347 -99.316408203703702,-19.291993899650947 -99.316408203703702,-13.798829970164547 -99.316408203703702,-8.305666040678148 -99.316408203703702,-2.812502111191748 -99.316408203703702,2.680661818294652 -99.316408203703702,8.173825747781052 -99.316408203703702,13.666989677267452 -99.316408203703702,19.160153606753852 -69.125979247246434,19.160153606753852 -38.935550290789166,19.160153606753852 -8.745121334331884,19.160153606753852 21.44530762212537,19.160153606753852 51.635736578582652,19.160153606753852 81.826165535039934,19.160153606753852 112.016594491497187,19.160153606753852 142.207023447954498,19.160153606753852 142.207023447954498,13.666989677267452 142.207023447954498,8.173825747781052 142.207023447954498,2.680661818294652 142.207023447954498,-2.812502111191748 142.207023447954498,-8.305666040678148 142.207023447954498,-13.798829970164547 142.207023447954498,-19.291993899650947 142.207023447954498,-24.785157829137347";
html,
body,
#map_canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<input type="button" onclick="toggleKml();" value="toggle KML" />
<input type="button" onclick="togglePolygon();" value="toggle Polygon" />
<script src="https://maps.googleapis.com/maps/api/js"></script>
<div id="map_canvas" style="border: 2px solid #3872ac;"></div>
Related
I am using the Google Maps API specifically the "Maps JavaScript API", and I have most of the JavaScript code done and the map is shown in my browser (Chrome).
But here is the issue, when I open the the file in Firefox browser or when I open the same file in other computers in their Chrome browser... the map will not show the right way. Mostly the issue is with the zoom feature.
On my Chrome the map will appear as following:
In firefox or some other computers the map will appear as following:
I tried changing the code in different ways, and reading the Google documentation again. I tried using different variations of
map.fitBounds(bounds);
map.panToBounds(bounds);
But I have not gotten any good results from it.
Here is the complete code
<div class="ui-panelgrid-cell ui-g-12 ui-md-12">
<style>
#map {
height: -webkit-fill-available;
display: block;
position: static !important;
}
body #mapOverFlow .ui-dialog .ui-dialog-content {
overflow: hidden;
}
</style>
<div id="map" style="position: relative; overflow: hidden;"></div>
<script>
function initialize() {
var userCoor = [
["<div><h1>JLSKYLL REDES</h1><div><p></p><p><b>22246338</b></p></div></div>", 9.381300800000002, -
84.14509079999999
],
["<div><h1>Lirio Lodge</h1><div><p>Lirio Lodge is the ideal place for lovers of nature, has a privileged location in front of the beautiful Laguna Madre of God, in the channels of Tortuguero.</p><p><b>22825003</b></p></div></div>",
9.94591, -84.11847569999999
]
];
var mapOptions = {
mapTypeId: google.maps.MapTypeId.ROADMAP,
zoom: 2
};
var marker, i, userCoordinate, map;
var bounds = new google.maps.LatLngBounds();
map = new google.maps.Map(document.getElementById("map"), mapOptions);
var userCoorPath = [new google.maps.LatLng(9.381300800000002, -84.14509079999999), new google.maps.LatLng(
9.94591, -84.11847569999999)];
userCoordinate = new google.maps.Polyline({
path: userCoorPath,
strokeColor: "#FF0000",
strokeOpacity: 1,
strokeWeight: 2
});
userCoordinate.setMap(map);
var infowindow = new google.maps.InfoWindow();
for (i = 0; i < userCoor.length; i++) {
marker = new google.maps.Marker({
position: new google.maps.LatLng(userCoor[i][1], userCoor[i][2]),
map: map
});
var loc = new google.maps.LatLng(marker.position.lat(), marker.position.lng());
bounds.extend(loc);
google.maps.event.addListener(marker, 'click', (function (marker, i) {
return function () {
infowindow.setContent(userCoor[i][0]);
infowindow.open(map, marker);
}
})(marker, i));
}
center = bounds.getCenter();
map.fitBounds(bounds);
map.panToBounds(bounds);
}
</script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=API_KEY&callback=initialize">
</script>
</div>
The map should be shown in your browser when you open the file and add the API_KEY. Now it may appear with the zoom, or i can appear all far away.
Try in Firefox and Chrome.
Your map has no center set. Note that this is a required parameter, but you never assign the value of center = bounds.getCenter() to your map instance. Try adding the code below:
const center = bounds.getCenter();
map.setCenter(center);
In addition, your map has a zoom level of 2. Change it to e.g. 8 if you don't want your map to appear all far away.
var mapOptions = {
mapTypeId: google.maps.MapTypeId.ROADMAP,
zoom: 8
};
Take a look at this jsfiddle for demonstration and guidance. It works regardless of browser.
Hope this helps you.
i have a problem with my places from google maps, i already have a functionality map with a file kml in my https server, but i don't want to download and upload the map every time I make changes, not work for me only embed I need manipulated with API, so this is my code:
var map;
var src = 'MY_SERVER/points_vl.kmz';
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
center: new google.maps.LatLng(20.63736, -105.22883),
zoom: 2,
});
loadKmlLayer(src, map);
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
var circle = 'http://www.nearby.org.uk/google/circle.kml.php?radius=5miles&lat='+position.coords.latitude+'&long='+position.coords.longitude;
loadKmlLayer(circle, map);
map.setCenter(pos);
setTimeout(function(){
var infowindow = new google.maps.InfoWindow({
map: map,
position: pos,
content: 'Current Location'
});
infowindow.setPosition(pos);
}, 2000);
});
}
}
function loadKmlLayer(src, map) {
var kmlLayer = new google.maps.KmlLayer(src, {
suppressInfoWindows: true,
preserveViewport: false,
map: map
});
google.maps.event.addListener(kmlLayer, 'click', function(event) {
var content = event.featureData.infoWindowHtml;
var testimonial = document.getElementById('capture');
testimonial.innerHTML = content;
});
}
This work fine, but have a way for direct the kml from my url of google maps places?
Using an existant Google 'My Places' map with Maps API v3 styling this thread have some idea, but not work, if you get a idea how make it will make it wonderful
Go to your "MyMap" map. Click on the three dots next to the name of the map, click on "Export to KML":
Choose the "Keep data up to date with network link KML (only usable online):
Rename the .kmz file to .zip, then open it and open the doc.kml file it contains. That file will have the direct link to the KML data specifying your "MyMap".
Use that link in a google.maps.KmlLayer
proof of concept fiddle
original MyMap
code snippet:
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 11,
center: {
lat: 41.876,
lng: -87.624
}
});
var ctaLayer = new google.maps.KmlLayer({
url: 'https://www.google.com/maps/d/kml?mid=1-mpfnFjp1e5JJ1YkSBjE6ZX_d9w',
map: map
});
}
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#map {
height: 100%;
}
<div id="map"></div>
<!-- add your own API key. -->
<script async defer src="https://maps.googleapis.com/maps/api/js?callback=initMap&key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk">
</script>
Need to implement a simple draggable map (no zoom), the pin should stay static in the centre, overlaying the map. Every time the map is moved/dragged under the static pin the positioning details of the pin are updated and I can grab those positioning details and display the address in input field above.
Probably a very simple task, I just don't have any experience with Google maps and it would be great if someone could point me either to a working example of this or to right API's/Libraries that I can use in my HTML5/Angular app. Would save me a lot of time researching. Thanks..
You can re-center the marker in a dragend event, and grab the new lat/long. If you want to convert the lat/long to a real world address, you can pass them to a reverse geocoder.
var newlat, newlong;
var latitude = 51.5;
var longitude = -0.12;
var coords = new google.maps.LatLng(latitude, longitude);
var mapOptions = {
zoom: 8,
center: coords,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(
document.getElementById("mapContainer"), mapOptions
);
var marker = new google.maps.Marker({
position: coords,
map: map,
draggable: true,
});
google.maps.event.addListener(map, 'dragend',
function() {
marker.setPosition(map.getCenter());
newlat = marker.getPosition().lat();
newlong = marker.getPosition().lng();
$('#coords').html(newlat + ', ' + newlong);
})
#mapContainer {
width: 400px;
height: 200px;
border: 1px solid #ebebeb;
}
#coords {
width: 380px;
padding: 10px;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="http://maps.google.com/maps/api/js"></script>
<div id="mapContainer"></div>
<br>
<div id="coords"></div>
I am finishing up a project I'm working on, and to improve user functionality, I want to have a page where the browser gets the user's current position (geolocation()), and fills out form fields with the latitude and longitude. However, once that happens, I want a marker placed on a google map that the user can drag, which will update in the form when they drag it. I know there has to be a way to do this, but I can't quite get it working. As of now, I have it fully functional to grab the user's location and fill out the form fields. I'm kind of struggling with the Google API, though. It doesn't help I'm not very well versed in Javascript (These functionalities are pretty much the only javascript I'm using throughout the whole large project). Attached is working code that gets position and fills out the input fields, and then I have my first attack at the Google maps API, which fails: The map simply comes up as a blank gray box with the zoom controls and street-view dragger, but they do nothing since it's all gray.
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&signed_in=true"></script>
<script>
var x=document.getElementById("latitude");
var y=document.getElementById("longitude");
function getLocation()
{
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition(showPosition);
}
else{x.innerHTML="Geolocation is not supported by this browser.";}
}
function showPosition(position) {
x.value=position.coords.latitude;
y.value=position.coords.longitude;
}
getLocation();
and here's the google api stuff that's failing (keeping in mind that this is just a hacked together attempt that I kind of figured wouldn't work). I'm wondering if the x and y values aren't immediately filling out and this is then getting called somehow, because if I hard-code in latitudes and longitudes instead of x and y, I get a functional map, although, obviously since x and y aren't being used there, it doesn't fill back in the form:
function initialize() {
var myLatlng = new google.maps.LatLng(x, y);
var mapOptions = {
zoom: 4,
center: myLatlng
}
var map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
title: 'Hello World!'
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
Finally, here's my two fields of the input form:
<p>
<i>Latitude:</i>
<input type="text" name="latitude" id="latitude" placeholder="latitude"><br>
</p>
<p>
<i>Longitude:</i>
<input type="text" name="longitude" id="longitude" placeholder="longitude"><br>
</p>
This is what I would do
<style>
#map-canvas {
height: 400px;
}
</style>
<div id="map-canvas"></div>
<p>
<i>Latitude:</i>
<input type="text" name="latitude" id="latitude" placeholder="latitude"><br>
</p>
<p>
<i>Longitude:</i>
<input type="text" name="longitude" id="longitude" placeholder="longitude"><br>
</p>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
<script>
var x=document.getElementById("latitude");
var y=document.getElementById("longitude");
// Make sure you have a default. You don't know if geolocation will find the user's location
var defaultLocation = new google.maps.LatLng(50.84498962150941, 4.349988162517548); // Manneken Pis, Brussels
var map;
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
}
else {
x.innerHTML = "Geolocation is not supported by this browser.";
////maybe you want to set a marker on the map anyway.
// markerOnClientPosition(defaultLocation);
}
}
function showPosition(position) {
x.value = position.coords.latitude;
y.value = position.coords.longitude;
if (map) {
markerOnClientPosition(new google.maps.LatLng(position.coords.latitude, position.coords.longitude));
}
}
getLocation();
function initialize() {
//var myLatlng = new google.maps.LatLng(Number(x), Number(y)); //
var mapOptions = {
zoom: 10,
center: defaultLocation, // myLatlng,
mapTypeId: google.maps.MapTypeId.HYBRID
}
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
}
function markerOnClientPosition(myLatlng) {
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
draggable: true,
title: 'You are here. Drag to exact location'
});
// attach a drag event
google.maps.event.addListener(marker, 'dragend', function() {
x.value = marker.getPosition().lat();
y.value = marker.getPosition().lng();
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
I always seem to solve things after I ask about them. After more digging, I found this page's top solution to be tailorable to my project.
Google Maps v3: need multiple draggable markers to update HTML input fields
Is there are way to retrieve a map from Google using the API so that it displays a list of local churches with churches with markers?
I have the basic syntax, and I have a basic API account setup, but I am not how/if I can use the type field.
var mapOptions = {
center: new google.maps.LatLng("-33.8670522", "151.1957362"),
zoom: 11,
scrollwheel: false,
streetViewControl: false,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("googlemaps"), mapOptions);
Yes, you can do this, using Google Places API.
I'll use JavaScript API, since you seem to have a map being built with such API.
As said in documentation:
The Places service is a self-contained library, separate from the main Maps API JavaScript code. To use the functionality contained within this library, you must first load it using the libraries parameter in the Maps API bootstrap URL:
<script src="https://maps.googleapis.com/maps/api/js?libraries=places"></script>
After this, using JavaScript Places API you can request places by type and a radius (in meters). The maximum allowed radius is 50.000 meters.
Here a piece of code that demonstrate this:
var request = {
location: sydney,
radius: 5000,
types: ['church']
};
var service = new gm.places.PlacesService(map);
service.nearbySearch(request, handlePlaceResponse);
Obs.: In this example, handlePlaceResponse is a callback to handle the response and create the markers. See in the complete example how it works.
This will request by churches in a 5km radius from Sydney point (lat: -33.8670522, lng: 151.1957362).
To overlay markers you'll need handle the response. In the example I used only name to put as content of InfoWindow. You can see details about the response here: Place Details Responses
So, a function to create markers look like this:
/**
* Creates marker with place information from response
*/
function createMarker(place) {
var marker = new google.maps.Marker({
map: map,
position: place.geometry.location
});
var infowindow = new google.maps.InfoWindow();
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(place.name);
infowindow.open(map, this);
});
}
Also, if you need, for types supported in place search, see this link: Place Type
Here an example using as point the used by you and 5000 meters for radius:
<html>
<head>
<title>Google Maps - Places Sample</title>
<style>
body {
margin: 0;
}
#map {
height: 600px;
width: 100%;
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?libraries=places"></script>
<script>
var gm = google.maps;
var map;
var bounds;
var service;
var infowindow;
var sydney = new gm.LatLng(-33.8670522, 151.1957362);
function initialize() {
var options = {
zoom: 15,
center: sydney,
mapTypeId: gm.MapTypeId.ROADMAP,
streetViewControl: false,
scrollwheel: false
};
map = new gm.Map(document.getElementById("map"), options);
var request = {
location: sydney,
radius: 5000,
types: ['church']
};
bounds = new gm.LatLngBounds();
infowindow = new gm.InfoWindow();
service = new gm.places.PlacesService(map);
service.nearbySearch(request, handlePlaceResponse);
}
/**
* Handle place response and call #createMarker to creat marker for every place returned
*/
function handlePlaceResponse(results, status) {
if (status == gm.places.PlacesServiceStatus.OK) {
for (var i = 0; i < results.length; i++) {
createMarker(results[i]);
}
}
map.fitBounds(bounds);
map.setCenter(bounds.getCenter());
}
/**
* Creates marker with place information from response
*/
function createMarker(place) {
var location = place.geometry.location;
var marker = new gm.Marker({
map: map,
position: location
});
bounds.extend(location);
gm.event.addListener(marker, 'click', function() {
infowindow.setContent(place.name);
infowindow.open(map, this);
});
}
gm.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map"></div>
</body>
</html>