Detecting which polyline-grids a line crosses - javascript

Last year I built an extensive multi-tiered system to create a grid of qtr-mins. It works well.
My client would now like to pass in lines (two nodes of LatLng) and would like me to return which Qtr Mins it touches. FWIW, a QtrMin is a polygon that is 1/60/4 (1/4 minute) by 1/60/4.
Below is the stripped down script. I have an entry function where I will pass in the line nodes and I will write an external function to pass out the QtrMins touched.
Part of the problem is that I have drawn my Qtr Mins from polylines but that is how it is.
I will be leveraging the script via Delphi and making a function call to pass in the Lat/Lng pairs.
function getQtrMinTouched(oLat,oLng, fLat,fLng){
// Lost and confused here
}
and depending how the result is returned, I will make a call through a com object to pass the QtrMin to my program. Passing in arguments to functions and passing out results are already solved. Including that here would contribute little but would entail several modules to simply run.
My question is: using the grids I create below, is there a way to determine which of those grids are touched by a line (LatLng, LatLng)? A line may span multiple grids. A line will always be defined as two nodes (LatLng, LatLng).
<html>
<head>
<title>Find your Qtr minute locator
</title>
<script type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?v=3.24&libraries=geometry">
</script>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
</head>
<body>
<div id="map-canvas" style="HEIGHT: 100%; WIDTH: 100%" onclick=""></div>
<div id="map"></div>
<script type="text/javascript">
var map;
var llOffset = 1/60/4;
var qtrNELatLngCode;
var qtrNorth;
var qtrEast;
var qtrSWLatLngCode;
var qtrSouth;
var qtrWest;
var latPolylines = [];
var lngPolylines = [];
var lngLabels = [];
function initialize() {
geocoder = new google.maps.Geocoder();
map = new google.maps.Map(document.getElementById("map-canvas"), {
center: new google.maps.LatLng(34.0, -84.0),
zoom: 16,
streetViewControl: true,
mapTypeId: google.maps.MapTypeId.ROADMAP,
scaleControl: true
});
google.maps.event.addListener(map, "idle", function () {
var sLat = map.getCenter().lat();
var sLng = map.getCenter().lng();
//external.ShowMarker(sLat,sLng);
createGridLines(map.getBounds());
});
} // initialize
google.maps.event.addDomListener(window, "load", initialize);
function createGridLines(bounds) {
for (var i = 0; i < latPolylines.length; i++) {
latPolylines[i].setMap(null);
}
latPolylines = [];
for (var j = 0; j < lngPolylines.length; j++) {
lngPolylines[j].setMap(null);
}
lngPolylines = [];
for (var k = 0; k < lngLabels.length; k++) {
lngLabels[k].setMap(null);
}
lngLabels = [];
if (map.getZoom() < 12) {
return;
}
var north = bounds.getNorthEast().lat();
var east = bounds.getNorthEast().lng();
var south = bounds.getSouthWest().lat();
var west = bounds.getSouthWest().lng();
// define the size of the grid
var topLat = Math.ceil(north / llOffset) * llOffset;
var rightLong = Math.ceil(east / llOffset) * llOffset;
var bottomLat = Math.floor(south / llOffset) * llOffset;
var leftLong = Math.floor(west / llOffset) * llOffset;
qtrNELatLngCode = ddToQM(topLat, rightLong);
qtrNorth = qtrNELatLngCode.substring(0, 5);
qtrEast = qtrNELatLngCode.substring(5, 12);
qtrSWLatLngCode = ddToQM(bottomLat, leftLong);
qtrSouth = qtrSWLatLngCode.substring(0, 5);
qtrWest = qtrSWLatLngCode.substring(5, 12);
for (var latitude = bottomLat; latitude <= topLat; latitude += llOffset) latPolylines.push(new google.maps.Polyline({
path: [
new google.maps.LatLng(latitude, leftLong), new google.maps.LatLng(latitude, rightLong)],
map: map,
geodesic: true,
strokeColor: "#0000FF",
strokeOpacity: 0.1,
strokeWeight: 1
}));
for (var longitude = leftLong; longitude <= rightLong; longitude += llOffset) lngPolylines.push(new google.maps.Polyline({
path: [
new google.maps.LatLng(topLat, longitude), new google.maps.LatLng(bottomLat, longitude)],
map: map,
geodesic: true,
strokeColor: "#0000FF",
strokeOpacity: 0.1,
strokeWeight: 1
}));
if ((map.getZoom() < 16)) {
for (var l = 0; l < lngLabels.length; l++) {
lngLabels[l].setMap(null);
}
lngLabels = [];
return;
} // set lngLabels to null
for (var x = 0; x < latPolylines.length; ++x) {
for (var y = 0; y < lngPolylines.length; ++y) {
var latLng = new google.maps.LatLng(latPolylines[x].getPath().getAt(0).lat(),
lngPolylines[y].getPath().getAt(0).lng());
var qtrLatLng = ddToQM(latLng.lat(), latLng.lng());
Does the line touch this grid? I would think that at point of drawing the vertices, I would test to see if the line (knowing the (latlng,latlng)).
lngLabels.push(new google.maps.Marker({
map: map,
position: latLng,
icon: {
url: "https://chart.googleapis.com/chart?"
+ "chst=d_bubble_text_small&chld=bbbr|"
+ qtrLatLng
+ "|FFFFFF|000000",
anchor: new google.maps.Point(126, 42)
}
}));
}
}
} // end createGridLines
function getQtrMinTouched(oLat,oLng, fLat,fLng){
// Lost and confused here
}
function ddToQM(alat, alng) {
var latResult, lngResult, dmsResult;
alat = parseFloat(alat);
alng = parseFloat(alng);
latResult = "";
lngResult = "";
latResult += getDms(alat);
lngResult += getDms(alng);
dmsResult = latResult + lngResult;
// Return the resultant string.
return dmsResult;
}
function getDms(val) {
// Required variables
var valDeg, valMin, valSec, interimResult;
var qtrMin;
val = Math.abs(val);
// ---- Degrees ----
valDeg = Math.floor(val);
valMin = Math.floor((val - valDeg) * 60);
valSec = Math.round((val - valDeg - valMin / 60) * 3600 * 1000) / 1000;
if (valSec == 60) {
valMin += 1;
valSec = 0;
}
if (valMin == 60) {
valMin += 1;
valSec = 0;
}
interimResult = valDeg + "";
if (valMin < 10) {
valMin = "0" + valMin;
}
interimResult += valMin + "";
switch (valSec) {
case 0 :
qtrMin = "D";
break;
case 15 :
qtrMin = "C";
break;
case 30 :
qtrMin = "B";
break;
case 45 :
qtrMin = "A";
break;
}
interimResult += qtrMin;
return interimResult;
}
</script>
</body>
</html>

Related

The route is not being plotted when the waypoints exceeded a certain amount

I first read a sets of coordinates in my local drive, then put them in
the xcoord and y coord to be start,waypts,destination which will be plotted on Google Map.
But i discovered that, once the coodinates exceeding a certain number,the route is not plotted anymore,but a road map without and route. changing travelmode also changing the number of effective waypoints. What can be done when i have >100 coordinates to be plotted? Also, i would like to change all the marker into default one but not the green one with letters on it.(After 26 points the marker become normal again.) Thank you very much.
I was first using the example provided in a question about 8 waypoints, which is here:
Plotting more than 8 waypoints in Google Maps v3
My code are as follow:
xcoord = [];
ycoord = [];
stops = [] ;
document.getElementById('file').onchange = function(){
alert('4');
var file = this.files[0];
var reader = new FileReader();
reader.onload = function(progressEvent){
var lines = this.result.split('\n');
for(var line = 0; line < lines.length; line++){
//alert(lines[line]);
var split = [];
split = lines[line].split(',');
window.xcoord.push(split[0]);
window.ycoord.push(split[1]);
}
alert('finish');
}
reader.readAsText(file);
};
jQuery(function() {
document.getElementById('button').onclick = function initMap(){
for(i = 0;i<xcoord.length;i++){
window.stops.push({"Geometry":{"Latitude":xcoord[i],"Longitude":ycoord[i]}});}
var map = new window.google.maps.Map(document.getElementById("map"));
// new up complex objects before passing them around
var directionsDisplay = new window.google.maps.DirectionsRenderer();
var directionsService = new window.google.maps.DirectionsService();
Tour_startUp(stops);
window.tour.loadMap(map, directionsDisplay);
window.tour.fitBounds(map);
if (stops.length > 1)
window.tour.calcRoute(directionsService, directionsDisplay);}});
function Tour_startUp(stops) {
if (!window.tour) window.tour = {
updateStops: function (newStops) {
stops = newStops;
},
// map: google map object
// directionsDisplay: google directionsDisplay object (comes in empty)
loadMap: function (map, directionsDisplay) {
var myOptions = {
zoom: 13,
center: new window.google.maps.LatLng(22.2830, 114.200),
mapTypeId: window.google.maps.MapTypeId.ROADMAP
};
map.setOptions(myOptions);
directionsDisplay.setMap(map);
},
fitBounds: function (map) {
var bounds = new window.google.maps.LatLngBounds();
// extend bounds for each record
jQuery.each(stops, function (key, val) {
var myLatlng = new window.google.maps.LatLng(val.Geometry.Latitude, val.Geometry.Longitude);
bounds.extend(myLatlng);
});
map.fitBounds(bounds);
},
calcRoute: function (directionsService, directionsDisplay) {
var batches = [];
var itemsPerBatch = 10; // google API max = 10 - 1 start, 1 stop, and 8 waypoints
var itemsCounter = 0;
var wayptsExist = stops.length > 0;
while (wayptsExist) {
var subBatch = [];
var subitemsCounter = 0;
for (var j = itemsCounter; j < stops.length; j++) {
subitemsCounter++;
subBatch.push({
location: new window.google.maps.LatLng(stops[j].Geometry.Latitude, stops[j].Geometry.Longitude),
stopover: true
});
if (subitemsCounter == itemsPerBatch)
break;
}
itemsCounter += subitemsCounter;
batches.push(subBatch);
wayptsExist = itemsCounter < stops.length;
// If it runs again there are still points. Minus 1 before continuing to
// start up with end of previous tour leg
itemsCounter--;
}
// now we should have a 2 dimensional array with a list of a list of waypoints
var combinedResults;
var unsortedResults = [{}]; // to hold the counter and the results themselves as they come back, to later sort
var directionsResultsReturned = 0;
for (var k = 0; k < batches.length; k++) {
var lastIndex = batches[k].length - 1;
var start = batches[k][0].location;
var end = batches[k][lastIndex].location;
// trim first and last entry from array
var waypts = [];
waypts = batches[k];
waypts.splice(0, 1);
waypts.splice(waypts.length - 1, 1);
var request = {
origin: start,
destination: end,
waypoints: waypts,
optimizeWaypoints: true,
travelMode: window.google.maps.TravelMode.WALKING
};
(function (kk) {
directionsService.route(request, function (result, status) {
if (status == window.google.maps.DirectionsStatus.OK) {
var unsortedResult = { order: kk, result: result };
unsortedResults.push(unsortedResult);
directionsResultsReturned++;
if (directionsResultsReturned == batches.length) // we've received all the results. put to map
{
// sort the returned values into their correct order
unsortedResults.sort(function (a, b) { return parseFloat(a.order) - parseFloat(b.order); });
var count = 0;
for (var key in unsortedResults) {
if (unsortedResults[key].result != null) {
if (unsortedResults.hasOwnProperty(key)) {
if (count == 0) // first results. new up the combinedResults object
combinedResults = unsortedResults[key].result;
else {
// only building up legs, overview_path, and bounds in my consolidated object. This is not a complete
// directionResults object, but enough to draw a path on the map, which is all I need
combinedResults.routes[0].legs = combinedResults.routes[0].legs.concat(unsortedResults[key].result.routes[0].legs);
combinedResults.routes[0].overview_path = combinedResults.routes[0].overview_path.concat(unsortedResults[key].result.routes[0].overview_path);
combinedResults.routes[0].bounds = combinedResults.routes[0].bounds.extend(unsortedResults[key].result.routes[0].bounds.getNorthEast());
combinedResults.routes[0].bounds = combinedResults.routes[0].bounds.extend(unsortedResults[key].result.routes[0].bounds.getSouthWest());
}
count++;
}
}
}
directionsDisplay.setDirections(combinedResults);
var legs = combinedResults.routes[0].legs;
// alert(legs.length);
for (var i=0; i < legs.length;i++){
var markerletter = "A".charCodeAt(0);
markerletter += i;
markerletter = String.fromCharCode(markerletter);
createMarker(directionsDisplay.getMap(),legs[i].start_location,"marker"+i,"some text for marker "+i+"<br>"+legs[i].start_address,markerletter);
}
var i=legs.length;
var markerletter = "A".charCodeAt(0);
markerletter += i;
markerletter = String.fromCharCode(markerletter);
createMarker(directionsDisplay.getMap(),legs[legs.length-1].end_location,"marker"+i,"some text for the "+i+"marker<br>"+legs[legs.length-1].end_address,markerletter);
}
}
});
})(k);
}
}
};
}
The Snap to road thing is done via loading coordinates using PHP and then
using the google api. the code is as follow(for less than 200 points):
<!DOCTYPE html>
<?php
$stringJoin = "";
$stringJoin2 = "";
$index = 0;
$handle = fopen($_GET['fileName'], "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
$index++;
if ($index ==99 ){
$stringJoin2 .= trim($line)."|";
}
if ($index >= 100) {
$stringJoin2 .= trim($line)."|";
if($index == 200){
break;
}
continue;
}
$stringJoin .= trim($line)."|";
}
fclose($handle); }
echo $index;
echo "<br>";
$stringJoin = substr($stringJoin, 0, -1);
$stringJoin2 = substr($stringJoin2, 0, -1);
echo $stringJoin;
echo "<br>";
echo $stringJoin2; ?>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Roads API Demo</title>
<style>
html, body, #map {
height: 100%;
margin: 0px;
padding: 0px
}
#panel {
position: absolute;
top: 5px;
left: 50%;
margin-left: -180px;
z-index: 5;
background-color: #fff;
padding: 5px;
border: 1px solid #999;
}
#bar {
width: 240px;
background-color: rgba(255, 255, 255, 0.75);
margin: 8px;
padding: 4px;
border-radius: 4px;
}
#autoc {
width: 100%;
box-sizing: border-box;
}
</style>
</head>
<body>
<input type="button" name="button" id="button">
<input type="file" name="file" id="file">
<div id="map"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script
src="https://maps.googleapis.com/maps/api/js?libraries=drawing,places"></script>
<script>
var apiKey = 'AIzaSyCk5PjtR_spPKrVowRS3A7I3IE4gX6Ctec';
var map;
var drawingManager;
var placeIdArray = [];
var placeIdArray2 = [];
var polylines = [];
var polylines2 = [];
var snappedCoordinates = [];
var snappedCoordinates2 = [];
document.getElementById('button').onclick = function initialize() {
alert("Start");
var mapOptions = {
zoom: 13,
center: {lat: 22.3030, lng: 114.200} };
map = new google.maps.Map(document.getElementById('map'), mapOptions);
runSnapToRoad();
runSnapToRoad2();}
// Snap a user-created polyline to roads and draw the snapped path
function runSnapToRoad() {
$.get('https://roads.googleapis.com/v1/snapToRoads', {
interpolate: true,
key: apiKey,
path: <?php echo '"'.$stringJoin.'"';?>}, function(data) {
processSnapToRoadResponse(data);
drawSnappedPolyline();
//getAndDrawSpeedLimits(); });}
// Store snapped polyline returned by the snap-to-road method.
function processSnapToRoadResponse(data) {
snappedCoordinates = [];
placeIdArray = [];
for (var i = 0; i < data.snappedPoints.length; i++) {
var latlng = new google.maps.LatLng(
data.snappedPoints[i].location.latitude,
data.snappedPoints[i].location.longitude);
snappedCoordinates.push(latlng);
placeIdArray.push(data.snappedPoints[i].placeId); }}
// Draws the snapped polyline (after processing snap-to-road response).
function drawSnappedPolyline() {
var snappedPolyline = new google.maps.Polyline({
path: snappedCoordinates,
strokeColor: 'black',
strokeWeight: 3 });
snappedPolyline.setMap(map);
polylines.push(snappedPolyline);}
</script>
<div id="bar">
<p class="auto"><input type="text" id="autoc"/></p>
<p><a id="clear" href="#">Click here</a> to clear map.</p>
</div>

Unexpected behaviour in famo.us javascript

The code below creates up the elements for a grid, and arranges it using the transformOut method. This part works fine, but I then want the grid to collapse in to the centre on mousedown, and spring back out again on mouseup. However, all subsequent calls to either the transformIn or transformOut function result in the items going in and out. A working example is here:
http://codepen.io/timsig/pen/JdXYwE
Code as follows, thanks for any help.
define('main', function (require, exports, module) {
var Engine = require('famous/core/Engine');
var View = require('famous/core/View');
var Surface = require('famous/core/Surface');
var Modifier = require('famous/core/Modifier');
var StateModifier = require('famous/modifiers/StateModifier');
var EventHandler = require('famous/core/EventHandler');
var PhysicsEngine = require('famous/physics/PhysicsEngine');
var Transitionable = require('famous/transitions/Transitionable');
var SpringTransition= require('famous/transitions/SpringTransition');
var Particle = require('famous/physics/bodies/Particle');
var Drag = require('famous/physics/forces/Drag');
var RepulsionForce = require('famous/physics/forces/Repulsion');
var Wall = require('famous/physics/constraints/Wall');
var Random = require('famous/math/Random');
var Transform = require('famous/core/Transform');
Transitionable.registerMethod('spring', SpringTransition);
var context = Engine.createContext();
var cols = 5;
var rows = 5;
var gridSize = Math.min(window.innerWidth, window.innerHeight) / 1.5;
var itemSize = gridSize / (cols + 1);
var gridItems = [];
var transformOutArray = [itemSize / 2 - gridSize / 2,
(itemSize / 2 - gridSize / 2) / 2,
0,
(gridSize / 2 - itemSize / 2) / 2,
gridSize / 2 - itemSize / 2];
var transformInArray = Array.prototype.slice.call(transformOutArray);
transformInArray.reverse();
var cameraView = new View();
var camera = new Modifier({
origin: [0.5, 0.5],
align: [0.5, 0.5]
});
context.add(camera).add(cameraView);
function createGridItems(){
for (var r = 0; r < rows; r += 1){
for (var c = 0; c < cols; c += 1){
var gridItem = new Surface({
size: [itemSize, itemSize],
properties:{
backgroundColor: '#aa62bb'
},
content: r + "," + c
});
gridItem.mod = new StateModifier({
origin: [0.5, 0.5],
align: [0.5, 0.5],
transform: Transform.identity
});
gridItem.idx = gridItems.length;
gridItem.transformOutrs = transformOutArray[r];
gridItem.transformOutcs = transformOutArray[c];
gridItem.transformInrs = transformInArray[r];
gridItem.transformIncs = transformInArray[c];
gridItems.push(gridItem);
cameraView.add(gridItem.mod).add(gridItem);
}
}
}
function transformOut(){
console.log('transform out')
for (var i = 0; i < gridItems.length; i+=1){
var index = i;
var gridItem = gridItems[index];
var tran = Transform.translate(gridItem.transformOutrs, gridItem.transformOutcs);
gridItem.mod.setTransform(tran, {
method: 'spring',
dampingRatio: 0.5,
period: 600
});
}
}
function transformIn(){
console.log('transform in');
for (var j = 0; j < gridItems.length; j+=1){
var index = j;
var gridItem = gridItems[index];
var tran = Transform.translate(gridItem.transformInrs, gridItem.transformIncs);
gridItem.mod.setTransform(tran, {
method: 'spring',
dampingRatio: 0.5,
period: 600
});
}
}
createGridItems();
console.log (transformOutArray);
console.log (transformInArray);
transformOut();
Engine.on('mousedown', transformIn);
Engine.on('mouseup', transformOut);
});
Setting the Transform back to the identity will return items back to their default on transform. Currently they are transitioning back to original once the new transform is set, then apply the new transform. You are only reversing their order with the new transforms.
function transformIn(){
console.log('transform in');
for (var j = 0; j < gridItems.length; j+=1){
var index = j;
var gridItem = gridItems[index];
gridItem.mod.setTransform(Transform.identity, {
method: 'spring',
dampingRatio: 0.5,
period: 600
});
}
}
Example snippet:
define('main', function (require, exports, module) {
var Engine = require('famous/core/Engine');
var View = require('famous/core/View');
var Surface = require('famous/core/Surface');
var Modifier = require('famous/core/Modifier');
var StateModifier = require('famous/modifiers/StateModifier');
var EventHandler = require('famous/core/EventHandler');
var PhysicsEngine = require('famous/physics/PhysicsEngine');
var Transitionable = require('famous/transitions/Transitionable');
var SpringTransition= require('famous/transitions/SpringTransition');
var Particle = require('famous/physics/bodies/Particle');
var Drag = require('famous/physics/forces/Drag');
var RepulsionForce = require('famous/physics/forces/Repulsion');
var Wall = require('famous/physics/constraints/Wall');
var Random = require('famous/math/Random');
var Transform = require('famous/core/Transform');
Transitionable.registerMethod('spring', SpringTransition);
var context = Engine.createContext();
var cols = 5;
var rows = 5;
var gridSize = Math.min(window.innerWidth, window.innerHeight) / 1.5;
var itemSize = gridSize / (cols + 1);
var gridItems = [];
var transformOutArray = [itemSize / 2 - gridSize / 2,
(itemSize / 2 - gridSize / 2) / 2,
0,
(gridSize / 2 - itemSize / 2) / 2,
gridSize / 2 - itemSize / 2];
var transformInArray = Array.prototype.slice.call(transformOutArray);
transformInArray.reverse();
var cameraView = new View();
var camera = new Modifier({
origin: [0.5, 0.5],
align: [0.5, 0.5]
});
context.add(camera).add(cameraView);
function createGridItems(){
for (var r = 0; r < rows; r += 1){
for (var c = 0; c < cols; c += 1){
var gridItem = new Surface({
size: [itemSize, itemSize],
properties:{
backgroundColor: '#aa62bb'
},
content: r + "," + c
});
gridItem.mod = new StateModifier({
origin: [0.5, 0.5],
align: [0.5, 0.5],
transform: Transform.identity
});
gridItem.idx = gridItems.length;
gridItem.transformOutrs = transformOutArray[r];
gridItem.transformOutcs = transformOutArray[c];
gridItem.transformInrs = transformInArray[r];
gridItem.transformIncs = transformInArray[c];
gridItems.push(gridItem);
cameraView.add(gridItem.mod).add(gridItem);
}
}
}
function transformOut(){
console.log('transform out');
for (var i = 0; i < gridItems.length; i+=1){
var index = i;
var gridItem = gridItems[index];
var tran = Transform.translate(gridItem.transformOutrs, gridItem.transformOutcs);
gridItem.mod.setTransform(tran, {
method: 'spring',
dampingRatio: 0.5,
period: 600
});
}
}
function transformIn(){
console.log('transform in');
for (var j = 0; j < gridItems.length; j+=1){
var index = j;
var gridItem = gridItems[index];
gridItem.mod.setTransform(Transform.identity, {
method: 'spring',
dampingRatio: 0.5,
period: 600
});
}
}
createGridItems();
console.log (transformOutArray);
console.log (transformInArray);
transformOut();
Engine.on('mousedown', transformIn);
Engine.on('mouseup', transformOut);
});
require(['main']);
<script src="http://requirejs.org/docs/release/2.1.16/minified/require.js"></script>
<script src="http://code.famo.us/lib/requestAnimationFrame.js"></script>
<script src="http://code.famo.us/lib/classList.js"></script>
<script src="http://code.famo.us/lib/functionPrototypeBind.js"></script>
<link rel="stylesheet" type="text/css" href="http://code.famo.us/famous/0.3.5/famous.css" />
<script src="http://code.famo.us/famous/0.3.5/famous.min.js"></script>
NOTE: setTransform is now deprecated in Famo.us
Deprecated: Prefer transformFrom with static Transform, or use a TransitionableTransform.

get NE and SW corners of a set of markers on a google map

I want to get NE and SW corners of a set of markers on a google map. Here I iterate over each marker. Does google or javascript provide a function that gets this with less iteration?
function fnSetBounds(){
var lowLat = 90;
var highLat = -90;
var lowLng = 180;
var highLng = -180;
for (var i = 0; i < myMarkers.length; i++) {
var myLat = myMarkers[i].position['k'];
var myLng = myMarkers[i].position['B'];
// catch low LAT
if (lowLat > myLat){
lowLat = myLat;
}
// catch high LAT
if (highLat < myLat) {
highLat = myLat;
}
// catch low LNG
if (lowLng > myLng){
lowLng = myLng;
}
// catch high lng
if (highLng < myLng) {
highLng = myLng;
}
}
var southWestCorner = new google.maps.LatLng(highLat, lowLng);
var northEastCorner = new google.maps.LatLng(lowLat, highLng);
var bounds = new google.maps.LatLngBounds();
bounds.extend(southWestCorner);
map.fitBounds(bounds);
bounds.extend(northEastCorner);
map.fitBounds(bounds);
}
I would do it this way, add all the positions to an empty bounds:
function fnSetBounds(){
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < myMarkers.length; i++) {
bounds.extend(myMarkers[i].getPosition());
}
map.fitBounds(bounds);
}

Rectangular Overlays appearing only after dragging the map

I have a lot of markers and I m using markerClusterer to display them on the map.Additionally on click of a checkbox I need to display a rectangular overlay (title) near all these markers.
I have written 2 functions as follows for creating the overlay and deleting it.
function createLabel(posi,name){
posicion = etiquetaNombre.length;
etiquetaNombre[posicion] = name;
var label = new Label({
position:posi,
map: map,
text:name
});
rectangleNombre[posicion]=label;
rectangleNombre[posicion].setMap(map);
console.log("add: etiquetaNombre",etiquetaNombre);
myfun();
}
function deletelabel(name){
for(var i = 0; i < etiquetaNombre.length; i++){
if(etiquetaNombre[i] == name){
rectangleNombre[i].setMap(null);
rectangleNombre.splice(i, 1);
etiquetaNombre.splice(i, 1);
}
}
console.log("delete marker"+name);
console.log("delete: etiquetaNombre",etiquetaNombre);
myfun();
}
I m invoking the createLabel function as follows:
var markerImage = new google.maps.MarkerImage(imageUrl,
new google.maps.Size(24, 32));
var latLng = new google.maps.LatLng(40, -100);
map = new google.maps.Map(document.getElementById('map'), {
zoom: 2,
center: new google.maps.LatLng(40, -100),
mapTypeId: google.maps.MapTypeId.ROADMAP
});
for (var i = 0; i < 10; ++i) {
var latLng = new google.maps.LatLng(data.photos[i].latitude,
data.photos[i].longitude);
var div=document.createElement('div');
var marker = new google.maps.Marker({
position: latLng,
draggable: false,
map: map,
title:"marker"+i
});
posi=marker.position;
name=marker.title;
createLabel(latLng,name);
markers.push(marker);
}
markerClusterer = new MarkerClusterer(map, markers);
Since I am using markerClusterer I had to customize it for my above requirement.I had done it as below.
Cluster.prototype.addMarker = function(marker) {
/// some lines
if (len < this.minClusterSize_ && marker.getMap() != this.map_) {
// Min cluster size not reached so show the marker.
marker.setMap(this.map_);
posi=marker.position;
name=marker.title;
createLabel(posi,name);
}
if (len == this.minClusterSize_) {
// Hide the markers that were showing.
for (var i = 0; i < len; i++) {
this.markers_[i].setMap(null);
name=this.markers_[i].title;
deletelabel(name);
}
}
if (len >= this.minClusterSize_) {
marker.setMap(null);
name=marker.title;
deletelabel(name);
}
this.updateIcon();
return true;
};
The myfun() is called on click of check box is as below.
function myfun(){
var element=document.getElementById('id1');
if(element.checked){
for(var i = 0; i < etiquetaNombre.length; i++){
var div = document.getElementById('normal-'+etiquetaNombre[i]);
if(div!=null){
div.style.display = "";
}
}
console.log("in my fun element checked",etiquetaNombre);
}
google.maps.event.addListener(map, 'bounds_changed', function () {
if(element.checked){
for(var i=0; i<etiquetaNombre.length; i++){
var div = document.getElementById('normal-'+etiquetaNombre[i]);
if(div!=null){
div.style.display = "";
}
}
}
});
}
The problem which I m facing here is that on zooming when the clustered markers are disintegrated the rectangular overlays do not appear for them.But on simply dragging the map it appears.Can anybody guide what I m doing wrong here.
[Edited]
function createLabel(xCenter , yCenter, nombre,banderaPersonalizada){
posicion = etiquetaNombre.length;
etiquetaNombre[posicion] = nombre;
var RectangleBounds = new google.maps.LatLngBounds(new google.maps.LatLng(yCenter,xCenter), new google.maps.LatLng((yCenter+1),(xCenter+1)));
rectangleNombre[posicion] = new RectangleNombre(RectangleBounds);
rectangleNombre[posicion].setMap(map);
}
function RectangleNombre(bounds, opt_weight, opt_color) {
this.bounds_ = bounds;
this.weight_ = opt_weight || 2;
this.color_ = opt_color || "#888888";
}
RectangleNombre.prototype = new google.maps.OverlayView();
RectangleNombre.prototype.onAdd = function(map) {
var idDiv = "normal-"+etiquetaNombre[posicion];
var div = document.createElement("div");
div.id = idDiv;
div.innerHTML = '<span style=" color:blue; font-family:arial; font-size:7.5pt; font-weight:900" > '+etiquetaNombre[posicion]+'</span>';
div.style.position = "absolute";
console.log("banderaCheckEtiqueta"+banderaCheckEtiqueta);
if(banderaCheckEtiqueta){
div.style.display = "";
} else {
div.style.display = "none";
}
this.getPanes().mapPane.appendChild(div);
this.map_ = map;
this.div_ = div;
}
RectangleNombre.prototype.draw = function() {
var proj = this.getProjection();
var c1 = proj.fromLatLngToDivPixel(this.bounds_.getSouthWest());
var c2 = proj.fromLatLngToDivPixel(this.bounds_.getNorthEast());
this.div_.style.width = "0px";
this.div_.style.height = "0px";
this.div_.style.left = c1.x - 12;
this.div_.style.top = c1.y + 2;
}

IE throws errors parsing data for GoogleMap

I have added map displaying some elements with specific geo position using Google.API. In modern browsers everything works fine, but IE7/8 as always has some problems. When trying to center map using lat/long parameters of each element I'm getting error stating , that 'lat' is "empty or not an object" in line var pos_lat = parseFloat(data_map[i]['lat']);. Still marker is added in the proper place using the same data. Anyone had this kind of problem ?
<script type='text/javascript'>
var map;
var mapStart = function(){
if(GBrowserIsCompatible()){
map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(51.961869,19.134521),6);
map.addControl(new GLargeMapControl());
var icon1 = new GIcon();
icon1.image = "/static/images/map_icon_1.png";
icon1.iconSize = new GSize(36, 30);
icon1.infoWindowAnchor = new GPoint(16,16);
icon1.iconAnchor = new GPoint(16,16);
var data_map = [{'url': '/bo/properties/property/7/', 'lat': '52.1898985', 'long': '20.8461914', 'name': 'asdfgh'},]
mapa.enableDoubleClickZoom();
mapa.enableContinuousZoom();
var bounds = new GLatLngBounds();
var maxlng =0;
var maxlat=0;
var minlng=0;
var minlat=0;
var positions=0;
var zoom = 0;
for (var i=0; i < data_map.length; i++){
var pos_lat = parseFloat(data_map[i]['lat']);
var pos_lon = parseFloat(data_map[i]['long']);
if(!isNaN(pos_lat) && !isNaN(pos_lon)){
positions = 1;
zoom++;
addMarker(pos_lat, pos_lon,{icon:icon1});
if (pos_lat < minlat || minlat==0){ minlat = pos_lat}
if (pos_lat > maxlat || maxlat==0){ maxlat = pos_lat}
if (pos_lon < minlng || minlng==0){minlng = pos_lon}
if (pos_lon > maxlng || maxlng==0){maxlng = pos_lon}
lat = minlat + (( maxlat - minlat)/2);
lng = minlng + (( maxlng - minlng)/2);
var allpoints = new GLatLng(lat,lng);
bounds.extend(allpoints);
}
}
if(positions){
if(zoom > 2){
mapa.setZoom(map.getBoundsZoomLevel(bounds)-2);
}
else{
map.setZoom(10);
}
map.setCenter(bounds.getCenter());
}
}
}
var addMarker = function(lat, lon, options){
point = new GLatLng(lat,lon);
var marker = new GMarker(point, options);
GEvent.addListener(marker, "click", function() {
marker.openInfoWindowHtml(info_box_html);
});
map.addOverlay(marker);
}
$(document).ready(function(){
mapStart();
});
window.onunload = function (){ GUnload()};
</script>
var data_map = [{'url': '/bo/properties/property/7/', 'lat': '52.1898985', 'long': '20.8461914', 'name': 'asdfgh'},]
There is an extra comma at the end of array.
Also try to use data_map[i].lat instead of data_map[i]['lat']

Categories

Resources