I want to draw multiple polygons in the same google map, what i need to do is to read latlngs from a listbox, they are in this way:
lat1,lng1,1
lat2,lng2,1
lat3,lng3,1
lat1,lng1,2
lat2,lng2,2
lat3,lng3,2
and depending on the value at the right(1 or 2) I will read the corresponding latlns and draw the polygon, actually i'm doing this, in my loop the polygons are painted but there´s a line connecting them, what can I do?,I mean, HOW CAN I DRAW POLYGONS WITHOUT THIS CONNECTING LINES?, thank you very much!!!
Here's my code:
<script type="text/javascript">
var bermudaTriangle=[];
var places = [];
var geoDataSplit;
function initialize() {
var mapDiv = document.getElementById('map_canvas');
var coords = document.getElementById("selPoly");
var map = new google.maps.Map(mapDiv, {
center: new google.maps.LatLng(19.3162200000000, -99.2204930000000),
zoom: 12,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var latlng;
for (var i = 0; i < coords.options.length; i++)
{
var geoData = coords.options[i].text;
geoDataSplit = geoData.split(",");
var counter = geoDataSplit[2];
for (geoDataSplit[2] = 1; geoDataSplit[2] <= 2; geoDataSplit[2]++)
{
if (counter == geoDataSplit[2]) {
latlng = new google.maps.LatLng(parseFloat(geoDataSplit[0]), parseFloat(geoDataSplit[1]));
places.push(latlng);
bermudaTriangle = new google.maps.Polygon({
paths: places,
strokeColor: "#FF0000",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0.35
});
}
}
}
bermudaTriangle.setMap(map);
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body style="font-family: Arial; border: 0 none;">
<form id="form1" runat="server">
<div>
<asp:ListBox ID="selPoly" runat="server"></asp:ListBox>
</div>
</form>
<div id="map_canvas" style="width: 1024px; height: 768px"></div>
</body>
Drawing polygons is drawing lines between points (the subsequent points you give, and possibly the first and last point on your list). When they enclose a space - you get a polygon and the space is filled with colour. The line is always there between the two subsequent points.
If you want separate polygons, you have to CREATE separate polygons (with new google.maps.Polygon). If all you get is a list of points, it is up to you to come up with or find an algorithm to detect that the space is already enclosed, and a new Polygon should be created.
By the way, with the algoritm as is now, the new google.maps.Polygon line could (and probably should) be pushed down, outside of the loop, in line preceding bermudaTriangle.setMap(map);
OH WAIT THERE ACTUALLY IS A SOLUTION. Or a half-solution at least. You can make the lines invisible (strokeOpacity: 0). The polygons will still be visible because of their filling, more or less like this:
Related
I have a very simple application (only one page) on which user draw polygons on the map and it also get lat, long, centre and radius of the circle that user drew.
I would like to limit user to draw only one circle as a source (Which I did and works fine), and then let him/her to select one or more destinations on the map. So, the first circle could be "source" and the next circles are "destinations"..
My question: how can I assign different variables to these circles in order to differentiate source place from destinations?
Here is my code (I used google api, Drawing library: https://developers.google.com/maps/documentation/javascript/examples/drawing-tools):
<script type="text/javascript">
(function () {
var circle;
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.MARKER,
drawingControl: true,
drawingControlOptions: {
position: google.maps.ControlPosition.TOP_CENTER,
drawingModes: [
google.maps.drawing.OverlayType.MARKER,
google.maps.drawing.OverlayType.CIRCLE,
google.maps.drawing.OverlayType.POLYGON,
google.maps.drawing.OverlayType.POLYLINE,
google.maps.drawing.OverlayType.RECTANGLE
]
},
markerOptions: {
icon: 'images/beachflag.png'
},
circleOptions: {
fillColor: '#ffff00',
fillOpacity: 1,
strokeWeight: 5,
clickable: false,
editable: true,
zIndex: 1
}
});
drawingManager.setMap(map);
google.maps.event.addListener(drawingManager, 'circlecomplete', onCircleComplete);
}
function onCircleComplete(shape) {
if (shape == null || (!(shape instanceof google.maps.Circle))) return;
if (circle != null) {
circle.setMap(null);
circle = null;
}
circle = shape;
var radius = circle.getRadius();
center = circle.getCenter();
var latitude = circle.getCenter().lat();
var longitude = circle.getCenter().lng();
}
google.maps.event.addDomListener(window, 'load', initialize);
})();
</script>
A simple approach:
Store all the circles, e.g. in an array, based on the length of the array you'll know if it's the first circle(source) or not(destination).
Setting different properties also isn't complicated, a google.maps.Circle is a MVCObject(and also a native JS-object), you may store custom properties e.g. via:
//vanilla javascript
shape.customProperty='customValue';
//MVCObject-specific, single property
shape.set('customProperty','customValue');
//MVCObject-specific, multiple properties
shape.setValues({customProperty :'customValue',
anotherProperty:'anotherValue'});
//shape-specific, multiple properties
shape.setOptions({customProperty :'customValue',
anotherProperty:'anotherValue'});
( Be sure that your custom property-names not compete with built-in names, e.g. center, radius etc.)
Possible implementation(stores a custom type-property for the circles, set to either source or destination):
function onCircleComplete(shape) {
var map=shape.getMap();
//create an array where we store the circles
if(!map.get('circles')){
map.set('circles',[]);
}
shape.setOptions(
(!map.get('circles').length)
?//first circle
{type:'source',
//a different fill when you want to
fillColor:'#ff0000'
}
://other circles
{type:'destination'}
);
//push the circles onto the array
map.get('circles').push(shape);
}
I have HTML5 canvas:
<canvas id="myCanvas" width="500" height="400"
style="border:1px solid #000000; background:#ccc;">
</canvas>
and here is easy to draw lines but line must be (x->max 500, y->max400) and thats ok.
But I how I can scale this canvas to show coordinates (latitude, longitude) - coordinates is high precision decimal values:
{"lat":"52.67554942424349","lng":"8.372654914855957"},{"lat":"52.67528921580262","lng":"8.373513221740723"},{"lat":"52.6759657545252","lng":"8.374114036560059"},{"lat":"52.682574466310314","lng":"8.37256908416748"},{"lat":"52.68356308524067","lng":"8.373942375183105"},{"lat":"52.68293869694087","lng":"8.375487327575684"},{"lat":"52.67685044320001","lng":"8.376259803771973"},{"lat":"52.6756535071859","lng":"8.379607200622559"},{"lat":"52.676017795531436","lng":"8.382096290588379"},{"lat":"52.68101344348877","lng":"8.380722999572754"},{"lat":"52.68351105322329","lng":"8.383641242980957"},
When I draw it on google map then looks like this:
IMAGE URL: http://i.stack.imgur.com/haTkH.png
How I can transform my decimal values from coordinates to show this coordinates from above on html5 canvas like on google map? Is there any way? I was spend 3 days to try to find solution for this probem? How that work?
thanks and sorry for my english
If you want to draw a lines in google maps, rather than using HTML 5, May be you can considering it using google maps api to draw a line.
if you want more info about how to using it. please read here.
And, if you want more detail about the API References, please read it here...
May be you should try this code snippet below, how to use this services from google maps api.
function initialize() {
var mapOptions = {
zoom: 15,
center: new google.maps.LatLng(-6.1839906,106.82296),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map-canvas'),
mapOptions);
var flightPlanCoordinates = [
new google.maps.LatLng(-6.175392,106.827153),
new google.maps.LatLng(-6.1827,106.82296),
new google.maps.LatLng(-6.1839906,106.82296),
new google.maps.LatLng(-6.1860599,106.8217262)];
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 src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
<div id="map-canvas" style="height:400px; width:400px"></div>
May be you can precise the line for what you need to...
I have a Google maps page that draws various polylines based on a bunch of coordinates. They all connect two points via a great circle polyline. All lines have the same color. These lines are routes on a network
I would now like to make the polylines in a fading color to indicate the profitability of the route, showing a green color for profitable routes and red for loss making routes. As each polyline has two possible profitabilities (from both originating points) the colors should fade over to the other color gradually.
I assume, I could split the polyline into two, showing each only half of the line, but then the color would not gradually fade into the other.
Is there a way to do that?
Currently I am creating the lines as follows:
var routes = [['CJU', 'SZX', 33.5112991333, 126.49299621582, 22.6392993927, 113.81099700928, 1, 7, 3163768],
['CJU', 'PEK', 33.5112991333, 126.49299621582, 40.08010101318, 116.58499908447, 0.5, 4, 3163766],
['CJU', 'PVG', 33.5112991333, 126.49299621582, 31.14340019226, 121.80500030518, 0.5, 4, 3163767],
['CJU', 'WUH', 33.5112991333, 126.49299621582, 30.78380012512, 114.20800018311, 0.5, 4, 3163769],];
function setRoutes(map, flights) {
for (var j = 0; j < flights.length; j++) {
var route = flights[j];
var infowindow = new google.maps.InfoWindow({ content: 'From '+route[0]+' to '+route[1]+' ', position: new google.maps.LatLng(route[4], route[5]) });
var flt = new google.maps.Polyline({path: [new google.maps.LatLng(route[2], route[3]), new google.maps.LatLng(route[4], route[5])], strokeColor: "#FF0000", strokeOpacity: route[6], strokeWeight: route[7], geodesic: true, url: 'http://domain.com/page.asp?F='+route[8] });
flt.setMap(map);
google.maps.event.addListener(flt, 'click', function() { NewWindow(this.url,'name','770','490','Yes');return false; });
var apt = new google.maps.MarkerImage('http://domain.com/marker/dot.png', null, null, new google.maps.Point(8,14), new google.maps.Size(20,20));
var dep = new google.maps.LatLng(route[2], route[3]);
var marker = new google.maps.Marker({position: dep, map: map, icon: apt, title: route[0]});
var arr = new google.maps.LatLng(route[4], route[5]);
var marker = new google.maps.Marker({position: arr, map: map, icon: apt, title: route[1]});
}
}
setRoutes(map, routes);
This works just fine, but I'm not sure how I could have the color gradually fade over from a color1 to a color2.
Thanks in advance.
The google maps documentation does not have any option to fade colors.
They will appear fixed, However a little bit of customization can be done but fading from one color to another is not supported.
Try giving colors in RGBA mode.
I mean instead of Giving colors in Hex mode e.g. #FF0000, you can use it's equivalent in RGBA mode e.g. rgba(255, 0, 0, 1).
To fade your colors in RGBA mode, change the value of last digit and keep it between 0 (transparent) and 1 (visible).
You can use this link to convert your Hex colors to RGBA.
I've got 10+ divs on a page and I dynamically load single marker lat/long data into each div, onclick. This produces a map, no problems. I am trying to get it so that I can parse multiple values of lat/long data into each div. Here is an example with single lat/long entry data
DEMO JSfiddle http://jsfiddle.net/x8dSP/2441/
<div id="map1" class="map" data-no="1" data-lat="53.716216" data-long="-1.96312"></div>
and here's my attempt using multiple markers per div
DEMO JSfiddle http://jsfiddle.net/x8dSP/2445/
<div id="map1" class="map" data-no="1" data-loc="53.716216,-1.582031|53.815121,-1.96312"></div>
It does not work and I am at a dead end on how to get it to work. Any help would be greatly appreciated
The marker position needs to be a google.maps.LatLng, not a comma separated string
the map needs to be initialized before using in the markerOptions
(among other things).
function mapOneInitialize(elem, index,loc) {
var centerPosition = new google.maps.LatLng('53.716216,-1.582031')
var options = {
zoom: 16,
center: centerPosition,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map[index] = new google.maps.Map(elem, options);
var loc = loc.split("|");
for (var x = 0; x < loc.length; x++) {
var coords = loc[x].split(',');
var marker = new google.maps.Marker({
position: new google.maps.LatLng(parseFloat(coords[0]),
parseFloat(coords[1])),
map: map[index]
});
}
};
working fiddle
Roughly a week ago, I ran into a problem: on a custom google-powered map, my Polygons would not show up, while Markers for the same coordinates are totally ok. Despite my efforts with the Google Maps API, it seems I cannot find why.
Here is a link to a screenshot of the map. Purple arrows and numbers are my addition, they show:
The google.maps.Marker I could place at the edges of my "region".
The artifact generated by the google.maps.Polygon code. It is red as expected, but completely out of place and weirdly flat.
Here is the part of the code where Markers and Polygons are generated:
var regionData = tecMap.regions[r];
var regionMapMarkers = new google.maps.MVCArray();
for (c in regionData.coords) {
var point = projection.worldToMap(regionData.coords[c]);
debugRegionPoints.push(point);
var thisLatLng = projection.fromPointToLatLng(point);
debugRegionLatLngs.push(thisLatLng);
regionMapMarkers.push(thisLatLng);
}
regionMapMarkers.forEach(function(latLng, m){
var marker = new google.maps.Marker({
position: latLng,
map: map,
title: '',
optimized: false
});
regionCorners.push(marker);
});
var paths = new google.maps.MVCArray();
paths.push(regionMapMarkers);
var region = new google.maps.Polygon({
fillColor: "#FF0000",
fillOpacity: 0.35,
map: map,
paths: paths,
strokeColor: "#FF0000",
strokeOpacity: 0.8,
strokeWeight: 2
});
regionPolys.push(region);
If you're wondering about the array of arrays, it's all on par with the Google Maps Javascript API.
If you want to have a look at the map and related scripts, you can find it here.
The code snippet is in Scripts/tectonicus.js, starting at line 659.
[Edit] Some debugging information:
It seems to be a rendering problem, not a "calculating" one.
From firebug console, in the map I linked, both
regionPolys[0].getPath().getArray();
and
for (i in regionCorners) {console.log(regionCorners[i].getPosition())};
will return
P { Na=0.20123958504464223, Oa=-22.5249097921875}
P { Na=-0.21702715474330336, Oa=-32.7277467}
P { Na=0.19466306397879407, Oa=-37.51230686484375}
P { Na=0.12889785332031245, Oa=-49.04594858671875}
If I'm right, it means they have the same coordinates, which is on par with the code.
[Edit2] New advances !
It seems that vectors have rendering problems when dealing with a custom projection, such as the one used to display this isometric Minecraft map. (Generated with Tectonicus)
After the last comments, I'm adding to the live code linked above two new debug Arrays,
debugRegionLatLngs and debugRegionPoints. Above code is updated so you can see what they contain.
[Edit3] Projection and coordinates
Crossing BicycleDude's research with mine, it's now almost certain that it's the custom projection that wrecks polygons. In fact, there is a possibly related bug in Google Maps' API.
This projection is used because Minecraft maps can be virtually infinite, and yet have to use a gmap, which wraps around after 360° longitude. Also related is the fact that ingame coordinates are rendered in an isometric way, while gmaps expects something more like the Mercator projection.
I tried tweaking the projection a bit, but had no interesting results so far.
Hmm, I looked at this further and I do see that sliver polygon. If you note your latitudes, they're extremely close to 0 degrees which means virtually a flat line near the equator. I validated this myself by pasting your coordinates into a brand new Google Maps sample and they do not appear to be spatially located with your markers, so, you need to review where the coordinate information is being manipulated, sorry, I know I didn't find your problem.
I modified Google Map's Bermuda triangle sample to use your coding style. i.e. I adopted your variables and followed the spirit of your code. This example display 3 markers and the draws a polygon for the Bermuda triangle.
<!DOCTYPE html>
<html>
<head>
<title>Bermuda Hack Triangle</title>
<meta name="viewport"
content="width=device-width, initial-scale=1.0, user-scalable=no">
<meta charset="UTF-8">
<style type="text/css">
#map_canvas {
width: 500px;
height: 500px;
}
</style>
<script type="text/javascript" scr="https://github.com/douglascrockford/JSON-js/blob/master/json2.js"></script>
<script type="text/javascript"
src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
var map;
function initialize() {
var myoptions = {
zoom: 4,
center: new google.maps.LatLng(25, -70),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(
document.getElementById('map_canvas'),
myoptions
);
// Create pseudo coordinates
var regionMapMarkers = new google.maps.MVCArray();
var p1 = new google.maps.LatLng(25, -80);
var p2 = new google.maps.LatLng(18, -66);
var p3 = new google.maps.LatLng(32, -64);
//p2.Qa += 360;
//p3.Qa -= 360;
regionMapMarkers.push(p1);
regionMapMarkers.push(p2);
regionMapMarkers.push(p3);
console.log(JSON.stringify(regionMapMarkers));
// Draw Markers
regionMapMarkers.forEach(function(latLng, m){
var marker = new google.maps.Marker(
{
position: latLng,
map: map,
title: '',
optimized: false
});
});
// Draw Polygon
var region = new google.maps.Polygon({
map: map,
paths: regionMapMarkers,
strokeColor: "#FF0000",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0.35
});
}
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
<body>
<div id="map_canvas"></div>
</body>
</html>
The sample works. If you were to run it you'll get the Bermuda triangle surrounded by markers. The question then lies, what can, in practice, impact your algorithm? So far, we've speculated that the Minecraft projection does something. I still believe that to be the case.
In order to validate that theory, I tried to wreck the Bermuda triangle sample. I tried adding and subtracting 360 degrees longitude to two points by uncommenting the following lines:
p2.Qa += 360;
p3.Qa -= 360;
What this does is it will still allow it to place the markers in the same location but the polygon fill goes absolutely spacko. I believe this is what is happening in your scenario.
What I then recommend for you to do is review coordinate system in your application. If you can choose new coordinates you can avoid such edge conditions from happening.
I noticed you're passing paths as an MVCArray which contains another MVCArray. Have you tried just passing a simple single-dimension array like in Google's example in the docs?
And do you need to call setMap() or is passing in the map property enough to make it render?
Below is Google's Polygon() code example... (from here)
function initialize() {
var myLatLng = new google.maps.LatLng(24.886436490787712, -70.2685546875);
var myOptions = {
zoom: 5,
center: myLatLng,
mapTypeId: google.maps.MapTypeId.TERRAIN
};
var bermudaTriangle;
var map = new google.maps.Map(document.getElementById("map_canvas"),
myOptions);
var triangleCoords = [
new google.maps.LatLng(25.774252, -80.190262),
new google.maps.LatLng(18.466465, -66.118292),
new google.maps.LatLng(32.321384, -64.75737),
new google.maps.LatLng(25.774252, -80.190262)
];
// Construct the polygon
// Note that we don't specify an array or arrays, but instead just
// a simple array of LatLngs in the paths property
bermudaTriangle = new google.maps.Polygon({
paths: triangleCoords,
strokeColor: "#FF0000",
strokeOpacity: 0.8,
strokeWeight: 2,
fillColor: "#FF0000",
fillOpacity: 0.35
});
bermudaTriangle.setMap(map);
}