I'm building a geofencing api with google maps api v3. I started from MapToolbar code :
http://nettique.free.fr/gmap/toolbar.html
I like it because it's really easy to customize like changing the icons and all the way the functions are called. I only use the polygon tool and I don't like the fact that you can't make convex angle when you add a point (only when you edit it after).
You can do it if you use drawingManager tools because the polygon is created only after you have completed the drawing :
https://developers.google.com/maps/documentation/javascript/examples/drawing-tools
But I don't like the default icons and I think the way the functions are called is not really user friendly. The thing is that I'm not able to call the functions by myself.
So, I'm looking for a way to start drawing without using the default drawing control as simple as calling the right function but I can't find it! Or maybe I can create polygons the same way without using drawingManager at all. Please help me!
I found it! If you want to hide the control menu, use drawingControl: false and if you want to change the drawing mode, use setDrawingMode() as explained here:
https://developers.google.com/maps/documentation/javascript/reference#DrawingManager
So, this is the new code starting in polygon drawing mode:
<!DOCTYPE html>
<html>
<head>
<title>Drawing tools</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<style>
html, body, #map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false&libraries=drawing"></script>
<script>
// ColorLuminance() is a little extra to have your strokeColor
// darker than your fillColor
function ColorLuminance(hex, lum) {
// validate hex string
hex = String(hex).replace(/[^0-9a-f]/gi, '');
if (hex.length < 6) {
hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];
}
lum = lum || 0;
// convert to decimal and change luminosity
var rgb = "#", c, i;
for (i = 0; i < 3; i++) {
c = parseInt(hex.substr(i*2,2), 16);
c = Math.round(Math.min(Math.max(0, c + (c * lum)), 255)).toString(16);
rgb += ("00"+c).substr(c.length);
}
return rgb;
}
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(-34.397, 150.644),
zoom: 8
};
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
var drawingManager = new google.maps.drawing.DrawingManager({
drawingMode: google.maps.drawing.OverlayType.POLYGON,
drawingControl: false,
polygonOptions: {
strokeWeight: 2,
strokeColor: ColorLuminance("#FF0000", -0.6),
strokeOpacity: 0.9,
fillColor: "#FF0000",
fillOpacity: 0.3
}
});
drawingManager.setMap(map);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map-canvas"></div>
</body>
</html>
Related
I'm using leaflet js and lantmateriet api for displaying map. But the map displaying empty white tiles in the browser. Map displaying fine with other api's like OSM. Im getting problem with lantmateriet api. This is my code.
var mapOptions = {
center: [59.4022, 13.5115],
zoom: 4
}
var map = new L.map('map', mapOptions);
L.tileLayer('https://api.lantmateriet.se/open/topowebb-ccby/v1/wmts/token/apikey/1.0.0/topowebb/default/3006/{z}/{y}/{x}.png', {
attribution: ''
}).addTo(map);
var marker = L.marker([59.3293, 18.0686]).addTo(map);
var m2 = L.marker([59.9139, 10.7522]).addTo(map);
m2.bindPopup("Oslo").addTo(map);
marker.bindPopup('Stockholm').addTo(map);
var latlngs = [
[59.9139, 10.7522],
[59.4022, 13.5115],
[59.3293, 18.0686]
];
var polyline = L.polyline(latlngs, {
color: 'red'
});
polyline.addTo(map);
var circleCenter = [59.4022, 13.5115]; // Center of the circle
var circleOptions = {
color: 'red',
fillColor: '#f03',
fillOpacity: 0.5,
}
// Creating a circle
var circle = L.circle(circleCenter, 10000, circleOptions);
circle.addTo(map); // Adding circle to the map
<!DOCTYPE html>
<html>
<head>
<title>Leaflet sample</title>
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
</head>
<body>
<div id="map" style="width: 900px; height: 580px"></div>
</body>
</html>
Please help me to solve this problem. Thanks in advance.
It seems you have a problem with authentication to lantmateriet (all requests get a 401 return code), I didn't see anywhere a token for authentication.
I think you have to check that first.
I am trying to draw a line between two coordinates on Google Maps.
The two coordinates I wish to use are:
4738.3319,N,
01903.2312,E,
4738.3219,N,
01903.7575,E,
I have converted these as follows:
47.383319,
19.032312
47.383219,
19.037575
I am using the code below:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Simple Polylines</title>
<style>
html, body, #map-canvas {
height: 100%;
margin: 0px;
padding: 0px
}
</style>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
<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 initialize() {
var mapOptions = {
zoom: 12,
center: new google.maps.LatLng(47.383219, 19.037575),
mapTypeId: google.maps.MapTypeId.TERRAIN
};
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
var flightPlanCoordinates = [
new google.maps.LatLng(47.383319, 19.032312),
new google.maps.LatLng(47.383219, 19.037575),
];
var flightPath = new google.maps.Polyline({
path: flightPlanCoordinates,
geodesic: true,
strokeColor: '#FF0000',
strokeOpacity: 1.0,
strokeWeight: 3
});
flightPath.setMap(map);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map-canvas"></div>
</body>
</html>
My problem is, that Google Maps draws the line somewhere on the southern border of Budapest, when they should point roughly to the norther border. Also, the longitude is almost good, it has a smaller inaccuracy (about 2 km), but latitude is absolutely wrong. I need at least a 15-20 meters accuracy. Am I using a wrong format?
Your coordinates are probably in a format where the first digits are degrees, the two digits before dot are minutes, and those after the dot are fractions of minutes. That is,
4738.3319,N, 01903.2312,E
means 47 degrees 38.3319 minutes north and 19 degrees 3.2312 minutes east.
To convert these to decimal degrees that are suitable for Google maps, you need to divide the minutes by 60 (as there are 60 minutes per degree), not 100. This gives you
47 + 38.3319/60 = 47.638865 N, 19 + 3.2312/60 = 19.053853 E
which is, indeed, on the northern side of Budapest.
I have written a code for displaying markers on the screen. And I have a text within the marker. The text is a 5 digit number which doesnot fit the marker. How can make the number to be within the marker?
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Google Map API V3: Add Marker</title>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
<style type="text/css">
body { margin: 20; padding: 20 }
#map_canvas{
width: 1024px;
height: 740px;
}
</style>
<script type="text/javascript">
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(47.576897,-122.419184),
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var locations = [
[47.648197,-122.282784,11500,"0"]
];
var map = new google.maps.Map(document.getElementById("map_canvas"),
mapOptions);
var shape = {
coord: [10, 10, 10, 20, 18, 20, 18 , 10],
type: 'poly'
};
for (i = 0; i < locations.length; i++) {
var myLatlng = new google.maps.LatLng(locations[i][0], locations[i][1]);
pinIcon = new google.maps.MarkerImage(
'http://chart.apis.google.com/chart?chst=d_map_pin_letter&chld='+locations[i][2]+'|808000|0000FF',
null,
null,
new google.maps.Point(140, 210),
new google.maps.Size(40, 60)
);
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
icon:pinIcon,
shape:shape,
title: locations[i][3]
});
}
}
</script>
</head>
<body onload="initialize()">
<div id="map_canvas"></div>
</body>
</html>
I want to print "11500" (locations[i][2]) inside my marker but when trying to do so it goes outside the marker.
The main issue is simply that you're using the wrong icon from the charts api. The pin type is of course not going to meet your needs for displaying the text; and you can't scale it after requesting it (as you seem to be trying in your code) since you'll be scaling the icon along with the text.
So two things to change:
MarkerIcon is deprecated, luckily it's easy to switch to Icon.
Use a different marker type that's designed for displaying text. Bubbles, probably.
Here is the relevant chunk of code that I just tested:
var myLatlng = new google.maps.LatLng(locations[i][0], locations[i][1]);
var pinIcon = {
url: 'http://chart.apis.google.com/chart?chst=d_bubble_text_small&chld=bb|'+locations[i][2]+'|C6EF8C|000000'
};
var marker = new google.maps.Marker({
position: myLatlng,
map: map,
icon: pinIcon,
title: locations[i][3]
});
I removed the shape attribute, because it's no longer valid with the new icon anyway. There is some image shifting during zoom, you can play with the attributes to fix that if you wish. And finally, there's different styles at that link to customize with.
Note: If this is to be used for a long time, know that the charts api is also deprecated, I think it's up until 2015.
In my app I want to store application-defined data on each latLng in a path.
I have got this to work using the code example below, but I would like to know whether this is an undocumented fluke that just 'happens' to work and could get broken in the future, or is it perfectly valid code that should always work?
In short, is 'getPath' guaranteed to return the same latLng objects that were passed in, or can it pass back new ones with the same lat and the same lng but anything else that google doesn't care about might not still be there?
Thanks for any assistance
Click on the line, and it should alert "one two three".
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map-canvas { height: 100% }
</style>
<script type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?key=MY_KEY&sensor=false">
</script>
<script type="text/javascript">
function initialize() {
var mapOptions = {
center: new google.maps.LatLng(52.0, -1.5),
zoom: 10,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map-canvas"),
mapOptions);
var polyline = new google.maps.Polyline({
map: map,
strokeColor: "blue",
strokeThicknedss: 2
});
polyline.setPath([
getLatLng(51.9, -1.4, "one"),
getLatLng(52.0, -1.5, "two"),
getLatLng(52.0, -1.6, "three")
]);
google.maps.event.addListener(polyline, "click", function() {
var path = this.getPath().getArray();
var datas = [];
for(var i = 0; i < path.length; i++) {
var ll = path[i];
datas.push(ll.data);
}
alert(datas.join("\n"));
});
}
function getLatLng(lat, lng, data) {
var ll = new google.maps.LatLng(lat, lng);
ll.data = data;
return ll;
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map-canvas"/>
</body>
</html>
Well according to the docs getPath() 'retrieves the first path'. And you've just set the path using setPath()... I'm not sure Google are going to mess with that data; your approach seems sound to me.
I found that the best way for storing polylines is to use Google's encoding function in the geometry library.
var polylineToStore = google.maps.geometry.encoding.encodePath(polyline.getPath());
This sets the polylineToStore variable to a string. When you want to reuse that encoded polyline you only need to decode it:
polyline.setPath(google.maps.geometry.encoding.decodePath(polylineToStore))
https://developers.google.com/maps/documentation/javascript/geometry#Encoding
I need to plot a set of coordinates on the map in response to a user selection, and when it happens, I'd like to pan the map to focus on that set of points. How can I find the smallest bounding box (LatLngBounds) that contains all of the coordinates?
In addition to the Stack Overflow post which #Crescent Fresh pointed to above (which is using the v2 API), the method you'd want to use is the LatLngBounds.extend().
Here's a complete example, using the v3 API:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Google Maps LatLngBounds.extend() Demo</title>
<script src="http://maps.google.com/maps/api/js?sensor=false"
type="text/javascript"></script>
</head>
<body>
<div id="map" style="width: 400px; height: 300px;"></div>
<script type="text/javascript">
var map = new google.maps.Map(document.getElementById('map'), {
mapTypeId: google.maps.MapTypeId.TERRAIN
});
var markerBounds = new google.maps.LatLngBounds();
var randomPoint, i;
for (i = 0; i < 10; i++) {
// Generate 10 random points within North East America
randomPoint = new google.maps.LatLng( 39.00 + (Math.random() - 0.5) * 20,
-77.00 + (Math.random() - 0.5) * 20);
// Draw a marker for each random point
new google.maps.Marker({
position: randomPoint,
map: map
});
// Extend markerBounds with each random point.
markerBounds.extend(randomPoint);
}
// At the end markerBounds will be the smallest bounding box to contain
// our 10 random points
// Finally we can call the Map.fitBounds() method to set the map to fit
// our markerBounds
map.fitBounds(markerBounds);
</script>
</body>
</html>
Screenshot: