Unable to draw a Curved Polyline using Here Maps JS Api - here-api

Unable to Draw a curved polyline using Here Maps JS API.
Trying to add the logic based on my previous findings.
It throws an error "Uncaught TypeError: arc.GreatCircle is not a constructor"
Any Suggestions on how to fix this ?
My Earlier Querstion
Here is my working JSFiddle which is trying to draw a curve to multiple spots.
//Step 1: initialize communication with the platform
// In your own code, replace variable window.apikey with your own apikey
var platform = new H.service.Platform({
apikey: window.apikey
});
var defaultLayers = platform.createDefaultLayers();
//Step 2: initialize a map - this map is centered over Europe
var map = new H.Map(document.getElementById('map'),
defaultLayers.vector.normal.map,{
center: {lat:52, lng:5},
zoom: 5,
pixelRatio: window.devicePixelRatio || 1
});
// add a resize listener to make sure that the map occupies the whole container
window.addEventListener('resize', () => map.getViewPort().resize());
//Step 3: make the map interactive
// MapEvents enables the event system
// Behavior implements default interactions for pan/zoom (also on mobile touch environments)
var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
// Create the default UI components
var ui = H.ui.UI.createDefault(map, defaultLayers);
window.addEventListener('resize', function() { map.getViewPort().resize(); });
var npoints = 100,
offset = 20;
// Now use the map as required...
//addPolylineToMap(map);
// Berlin -> Chicago0
add([52.51607,13.37699],[41.88425,-87.63245], { style: { strokeColor : "#00FF00", lineWidth : 5, lineDash: [3], lineHeadCap: "arrow-head", lineTailCap: "arrow-tail"} });
// Tokyo -> san Francisco
add([35.68019,139.81194],[37.77712,-122.41964], {style: { strokeColor: "rgba(0,0,255,0.7)", lineWidth: 15, lineDash: [1], lineHeadCap: "arrow-head", lineTailCap: "arrow-tail"} });
// Berlin -> Melbourne
add([52.51607,13.37699],[-37.81753,144.96715], { style: { strokeColor : "rgba(255,0,255,0.7)", lineWidth : 5, lineDash: [3], lineHeadCap: "arrow-head", lineTailCap: "arrow-tail"} });
// Berlin -> Paris -> Paris -> London
add([52.51607,13.37699],[48.85721, 2.34144], { style: { strokeColor : "rgba(0,255,0,0.7)", lineWidth : 5, lineDash: [3], lineHeadCap: "arrow-head", lineTailCap: "arrow-tail"} });
add([48.85721, 2.34144],[51.50643,-0.12721], { style: { strokeColor : "rgba(255,255,0,0.7)", lineWidth : 5, lineDash: [3], lineHeadCap: "arrow-head", lineTailCap: "arrow-tail"} });
function add(s,e,options) {
var arc = {};
arc.Coord = Coord;
arc.Arc = Arc;
arc.GreatCircle = GreatCircle;
var start_ll = new H.geo.Point(s[0],s[1]),
end_ll = new H.geo.Point(e[0],e[1]),
start_coord = {x: start_ll.lng, y:start_ll.lat},
end_coord = {x:end_ll.lng, y:end_ll.lat};
description = ''+s[0]+','+s[1]+'=>'+e[0]+','+e[1]+'',
gc0 = new arc.GreatCircle(start_coord,end_coord, {'name': 'line', 'color':'#ff7200','description':description}),
line0 = gc0.Arc(npoints,{offset:offset}),
strip = line0.strip();
map.addObject(new H.map.Polyline(strip, options));
}
var D2R = Math.PI / 180;
var R2D = 180 / Math.PI;
var Coord = function(lon, lat) {
this.lon = lon;
this.lat = lat;
this.x = D2R * lon;
this.y = D2R * lat;
};
Coord.prototype.view = function() {
return String(this.lon).slice(0, 4) + ',' + String(this.lat).slice(0, 4);
};
Coord.prototype.antipode = function() {
var anti_lat = -1 * this.lat;
var anti_lon = (this.lon < 0) ? 180 + this.lon : (180 - this.lon) * -1;
return new Coord(anti_lon, anti_lat);
};
var LineString = function() {
this.coords = [];
this.length = 0;
};
LineString.prototype.move_to = function(coord) {
this.length++;
this.coords.push(coord);
};
var Arc = function(properties) {
this.properties = properties || {};
this.geometries = [];
};
Arc.prototype.json = function() {
if (this.geometries.length <= 0) {
return { 'geometry': { 'type': 'LineString', 'coordinates': null }, 'type': 'Feature', 'properties': this.properties };
} else if (this.geometries.length == 1) {
return { 'geometry': { 'type': 'LineString', 'coordinates': this.geometries[0].coords }, 'type': 'Feature', 'properties': this.properties };
} else {
var multiline = [];
for (var i = 0; i < this.geometries.length; i++) {
multiline.push(this.geometries[i].coords);
}
return { 'geometry': { 'type': 'MultiLineString', 'coordinates': multiline }, 'type': 'Feature', 'properties': this.properties };
}
};
Arc.prototype.strip = function() {
var s = H.geo.Strip ? new H.geo.Strip() : new H.geo.LineString();
for (var i = 0; i < this.geometries.length; i++) {
if (this.geometries[i].coords.lenght !== 0) {
var coords = this.geometries[i].coords;
for (var j = 0; j < coords.length; j++) {
var p = new H.geo.Point(coords[j][1], coords[j][0]);
s.pushPoint(p);
}
}
}
return s;
}
var GreatCircle = function(start, end, properties) {
if (!start || start.x === undefined || start.y === undefined) {
throw new Error("GreatCircle constructor expects two args: start and end objects with x and y properties");
}
if (!end || end.x === undefined || end.y === undefined) {
throw new Error("GreatCircle constructor expects two args: start and end objects with x and y properties");
}
this.start = new Coord(start.x, start.y);
this.end = new Coord(end.x, end.y);
this.properties = properties || {};
var w = this.start.x - this.end.x;
var h = this.start.y - this.end.y;
var z = Math.pow(Math.sin(h / 2.0), 2) + Math.cos(this.start.y) * Math.cos(this.end.y) * Math.pow(Math.sin(w / 2.0), 2);
this.g = 2.0 * Math.asin(Math.sqrt(z));
if (this.g == Math.PI) {
throw new Error('it appears ' + start.view() + ' and ' + end.view() + " are 'antipodal', e.g diametrically opposite, thus there is no single route but rather infinite");
} else if (isNaN(this.g)) {
throw new Error('could not calculate great circle between ' + start + ' and ' + end);
}
};
#map {
width: 95%;
height: 450px;
background: grey;
}
<script src="https://heremaps.github.io/maps-api-for-javascript-examples/test-credentials.js"></script>
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=yes">
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Polyline on the Map</title>
<link rel="stylesheet" type="text/css" href="https://js.api.here.com/v3/3.1/mapsjs-ui.css" />
<link rel="stylesheet" type="text/css" href="demo.css" />
<link rel="stylesheet" type="text/css" href="styles.css" />
<link rel="stylesheet" type="text/css" href="../template.css" />
<script type="text/javascript" src='../test-credentials.js'></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-core.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-service.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-ui.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-mapevents.js"></script>
</head>
<body id="markers-on-the-map">
<div id="map"></div>
<script type="text/javascript" src='demo.js'></script>
</body>
</html>

this is simple: the var GreatCircle is not defined yet but program code invoke GreatCircle
We moved some parts of code through each together
but any way there is error GreatCircle doesn't have 'arc' property defined.
there is this module https://demo.support.here.com/javascripts/examples/v31/geodesic-polyline.js
but you needs Bézier curve: https://en.wikipedia.org/wiki/B%C3%A9zier_curve
I found some implementation on this https://habr.com/ru/post/163073/ - (but in russian) - there a curve consists from lines based on 100 points (step 0.01)
flow = getBezierCurve(new Array(arr[0], arr[1], arr[2], arr[3]), 0.01);
drawLines(ctx, flow, 10);
In JS API wasn't implemented functionality of like Bézier curve
but search in google on "bezier curve javascript example code" - if you get points of curve you can use in JS API map.screenToGeo every point and plot it on the map

Related

Pedestrian and bicycle route longer then car route

I'm using Here Maps API for calculating routes, most of them are for bycicle and pedestrian.
What I found very strange, is that sometimes the car-route is much smaller then the pedestrian or bicycle route.
I have one example in attachement (images route pedestrian and car).
This is from adres:
Steenweg 66, 9473 Denderleeuw, Belgium
To
Grooten Moortelhoek 17, 9473 Denderleeuw, Belgium
If I do the same in Google Maps, then it's ok...
Any suggestions …
Best regards
Bart
Code:
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
<script src="http://js.api.here.com/v3/3.0/mapsjs-core.js" type="text/javascript" charset="utf-8"></script>
<script src="http://js.api.here.com/v3/3.0/mapsjs-service.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-ui.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-mapevents.js"></script>
<link rel="stylesheet" type="text/css" href="https://js.api.here.com/v3/3.0/mapsjs-ui.css?dp-version=1526040296" />
</head>
<body>
<div id="mapContainer" style="width: 67%; height: 100%; float:left; border: 1px solid black"></div>
<div id="panel" style="position:absolute; width:29%; left:67%; height:97%; background:inherit; " ></div>
<script>
var url = window.location.toString();
var appid = '';
var appcode = '';
var typeaction = '';
var formatadres = '';
var fromadres = '';
var toadres = '';
var fromlatitude = '';
var fromlongitude = '';
var tolatitude = '';
var tolongitude = '';
var minrelevance = 0;
var routemode = '';
// Create the parameters for the routing request:
// var routingParameters = {
// // The routing mode:
// mode: 'fastest;car',
// // The start point of the route:
// waypoint0: fromlatlng,
// // The end point of the route:
// waypoint1: tolatlng,
// // To retrieve the shape of the route we choose the route
// representation: 'display',
// routeattributes : 'waypoints,summary,shape,legs',
// };
// omzetten van tijd in minuten en seconden
Number.prototype.toMMSS = function () {
return Math.floor(this / 60) +' min. '+ (this % 60) + ' sec.';
}
//get the parameters from url
url.match(/\?(.+)$/);
var params = RegExp.$1;
readUrlParameters(params);
// Initialize the platform object:
var platform = new H.service.Platform({
'app_id': appid,
'app_code': appcode
});
var defaultLayers = platform.createDefaultLayers();
var map = new H.Map(
document.getElementById('mapContainer'),
defaultLayers.normal.map, {
center: {lat: 50.8121, lng: 4.2190},
zoom: 9
});
var routeInstructionsContainer = document.getElementById('panel');
var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
var ui = H.ui.UI.createDefault(map, defaultLayers);
// Get an instance of the routing service:
var router = platform.getRoutingService();
// Get an instance of the geocoding service:
var geocoder = platform.getGeocodingService();
// CALLBACK FUNCTIONS
// Define a callback function to process the reverse geocoding response:
var onShowlatlong = function(result) {
var location = result.Response.View[0].Result[0];
// Create an InfoBubble at the returned location with
// the address as its contents:
// ui.addBubble(new H.ui.InfoBubble({
// lat: location.Location.DisplayPosition.Latitude,
// lng: location.Location.DisplayPosition.Longitude
// }, { content: '<p class="H_ib_body">' + location.Location.Address.Label + '</p>'}));
// Create a marker for the point:
var adressMarker = new H.map.Marker({
lat: location.Location.DisplayPosition.Latitude,
lng: location.Location.DisplayPosition.Longitude
});
// Add the route polyline and the two markers to the map:
map.addObjects([adressMarker]);
map.setCenter({lat: location.Location.DisplayPosition.Latitude, lng: location.Location.DisplayPosition.Longitude});
map.setZoom(17);
};
// Define a callback function to process the geocoding response:
var onShowadress = function(result) {
var locations = result.Response.View[0].Result,
position,
marker;
// alert(result.Response.View[0].Result[0].Relevance * 100);
if (result.Response.View[0].Result[0].Relevance * 100 < minrelevance) {
alert("Adres niet gevonden");
return;
}
// Add a marker for each location found
for (i = 0; i < locations.length; i++) {
position = {
lat: locations[i].Location.DisplayPosition.Latitude,
lng: locations[i].Location.DisplayPosition.Longitude
};
// alert(result.Response.View[0].Result[0].MatchLevel);
document.getElementById("fromLatitudechar").value = position.lat;
document.getElementById("fromLongitudechar").value = position.lng;
document.getElementById("fromRelevance").value = result.Response.View[0].Result[0].Relevance;
marker = new H.map.Marker(position);
map.addObject(marker);
map.setCenter({lat: position.lat, lng: position.lng});
map.setZoom(17);
}
};
// Define a callback function to process the calcroutlatlng:
var onCalcRoutelatlng = function(result) {
var route,
routeShape,
startPoint,
endPoint,
linestring;
if (typeof result.response === 'undefined') {
alert("Route niet gevonden");
return;
}
if(result.response.route) {
// Pick the first route from the response:
route = result.response.route[0];
// Pick the route's shape:
routeShape = route.shape;
// Create a linestring to use as a point source for the route line
linestring = new H.geo.LineString();
// Push all the points in the shape into the linestring:
routeShape.forEach(function(point) {
var parts = point.split(',');
linestring.pushLatLngAlt(parts[0], parts[1]);
});
// Retrieve the mapped positions of the requested waypoints:
startPoint = route.waypoint[0].mappedPosition;
endPoint = route.waypoint[1].mappedPosition;
// Create a polyline to display the route:
var routeLine = new H.map.Polyline(linestring, {
style: { strokeColor: 'blue', lineWidth: 5 },
arrows: { fillColor: 'white', frequency: 5, width: 1, length: 1 }
});
// Create a marker for the start point:
var startMarker = new H.map.Marker({
lat: startPoint.latitude,
lng: startPoint.longitude
});
// Create a marker for the end point:
var endMarker = new H.map.Marker({
lat: endPoint.latitude,
lng: endPoint.longitude
});
// Add the route polyline and the two markers to the map:
map.addObjects([routeLine, startMarker, endMarker]);
// Set the map's viewport to make the whole route visible:
map.setViewBounds(routeLine.getBounds());
addWaypointsToPanel(route.waypoint);
addManueversToPanel(route);
addSummaryToPanel(route.summary);
document.getElementById("distance").value = route.summary.distance;
//alert(route.summary.distance);
//alert(route.summary)
// toonAfstand(route.summary);
}
};
// END CALLBACK FUNCTIONS
// functie aanroepen om taal naar het Nederlands te zetten
switchMapLanguage(map , platform);
switch(typeaction){
case 'showadres': {
if (formatadres == "latlng") {
var reverseGeocodingParams = {
// prox: '51.20866,3.18413',
prox: fromadres,
mode: 'retrieveAddresses',
maxresults: 1
};
geocoder.reverseGeocode(reverseGeocodingParams, onShowlatlong, function(e) {
alert(e);
});
}
else {
var geocodingParams = {
searchText: fromadres
};
// Call the geocode method with the geocoding parameters,
// the callback and an error callback function (called if a
// communication error occurs):
geocoder.geocode(geocodingParams, onShowadress, function(e) {
alert(e);
});
}
break;
};
case 'showpin': {
var adressMarker = new H.map.Marker({
lat: fromlatitude,
lng: fromlongitude
});
// Add the route polyline and the two markers to the map:
map.addObjects([adressMarker]);
map.setCenter({lat: fromlatitude, lng: fromlongitude});
map.setZoom(17);
break;
}
// mode=shortest;car;traffic:disabled
case 'calcroutelatlng': {
var fromlatlng = 'geo!' + fromlatitude + ',' + fromlongitude;
var tolatlng = 'geo!' + tolatitude + ',' + tolongitude;
var routingParameters = {
// The routing mode:
mode: routemode,
// The start point of the route:
waypoint0: fromlatlng,
// The end point of the route:
waypoint1: tolatlng,
// To retrieve the shape of the route we choose the route
representation: 'display',
routeattributes : 'waypoints,summary,shape,legs',
maneuverattributes: 'direction,action',
language: 'nl-nl'
};
router.calculateRoute(routingParameters, onCalcRoutelatlng,
function(error) {
alert(error.message);
});
break;
}
};
// functie om map in het nederlands te krijgen, dit wordt aangeroepen bij het laden van de map
function switchMapLanguage(map, platform){
var mapTileService = platform.getMapTileService({type: 'base'}),
// Our layer will load tiles from the HERE Map Tile API
dutchMapLayer = mapTileService.createTileLayer(
'maptile',
'normal.day',
512,
'png8',
{lg: 'DUT'}
);
map.setBaseLayer(dutchMapLayer);
ui.removeControl('mapsettings');
}
function readUrlParameters (urlParameters) {
// split up the query string and store in an
// associative array
var urlParameters = urlParameters.split("&");
var queryStringList = {};
for(var i=0;i<urlParameters.length;i++)
{
var tmp = urlParameters[i].split("=");
queryStringList[tmp[0]] = unescape(tmp[1]);
}
appid = queryStringList["appid"];
appcode = queryStringList["appcode"];
typeaction = queryStringList["action"];
formatadres = queryStringList["formatadres"];
fromadres = queryStringList["adress1"];
minrelevance = queryStringList["minrelevance"];
fromlatitude = queryStringList["fromlat"];
fromlongitude = queryStringList["fromlng"];
tolatitude = queryStringList["tolat"];
tolongitude = queryStringList["tolng"];
routemode = queryStringList["routemode"];
}
function addWaypointsToPanel (waypoints){
var nodeH3 = document.createElement('h5'),
waypointLabels = [],
i;
nodeH3.style.marginLeft = '1%';
for (i = 0; i < waypoints.length; i += 1) {
waypointLabels.push(waypoints[i].label)
}
nodeH3.textContent = waypointLabels.join(' - ');
routeInstructionsContainer.innerHTML = '';
routeInstructionsContainer.appendChild(nodeH3);
}
function addManueversToPanel(route){
var nodeOL = document.createElement('ol'),
i,
j;
nodeOL.style.fontSize = 'small';
nodeOL.style.marginLeft ='2%';
nodeOL.style.marginRight ='2%';
nodeOL.className = 'directions';
// Add a marker for each maneuver
for (i = 0; i < route.leg.length; i += 1) {
for (j = 0; j < route.leg[i].maneuver.length; j += 1) {
// Get the next maneuver.
maneuver = route.leg[i].maneuver[j];
var li = document.createElement('li'),
// spanArrow = document.createElement('span'),
spanInstruction = document.createElement('span');
// spanArrow.className = 'arrow ' + maneuver.action;
spanInstruction.innerHTML = maneuver.instruction;
//li.appendChild(spanArrow);
li.appendChild(spanInstruction);
nodeOL.appendChild(li);
}
}
routeInstructionsContainer.appendChild(nodeOL);
}
function addSummaryToPanel(summary){
var summaryDiv = document.createElement('div'),
content = '';
content += '<b>Totale afstand</b>: ' + (summary.distance / 1000) + 'km. <br/>';
content += '<b>Reistijd</b>: ' + summary.travelTime.toMMSS() + ' (huidig verkeer)';
summaryDiv.style.fontSize = 'small';
summaryDiv.style.marginLeft ='2%';
summaryDiv.style.marginRight ='2%';
summaryDiv.innerHTML = content;
routeInstructionsContainer.appendChild(summaryDiv);
}
</script>
<form method="post">
<input name="fromLatitudechar" id="fromLatitudechar" type="hidden">
<input name="fromLongitudechar" id="fromLongitudechar" type="hidden">
<input name="toLatitudechar" id="toLatitudechar" type="hidden">
<input name="toLongitudechar" id="toLongitudechar" type="hidden">
<input name="fromRelevance" id="fromRelevance" type="hidden">
<input name="toRelevance" id="toRelevance" type="hidden">
<input name="distance" id="distance" type="hidden">
</form>
</body>
</html>
We checked the routing result between two addresses with route api.
And there is a restriction to turn left from Steenweg to Hertstraat. The location lat long is 50.906072,4.054588.
We will check the restriction whether exit or not in real world and update it.
Thank you!

Google Earth Network Link with Fusion Heat Map

So I have created a heat map in Fusion Tables, obtained a API key and copied the code into the link in Google Earth Network Link add. I did not get the resulting heat map to populate in Google Earth. I've set the sharing to Public and Unlisted but neither bears any fruit. Can anyone tell me what steps I am missing to get the heat map to populate in Google Earth?
Here is my obtained code (XXX'd out my API key)
<!DOCTYPE html>
<html>
<head>
<meta name="viewport"></meta>
<title>Copy of Heat Map - Google Fusion Tables</title>
<style type="text/css">
html, body, #googft-mapCanvas {
height: 300px;
margin: 0;
padding: 0;
width: 500px;
}
</style>
<script type="text/javascript" src="https://maps.google.com/maps/api/js?v=3&libraries=visualization"></script>
<script type="text/javascript">
if (window.location.protocol == "file:") {
alert('This script only works when loaded from a web server,' +
' not from a file on your computer.');
}
function ftOnLoadClientApi() {
gapi.client.setApiKey('XxxXxxXxxxXx');
}
</script>
<script type="text/javascript" src="https://apis.google.com/js/client.js?onload=ftOnLoadClientApi">
</script>
<script type="text/javascript">
var map;
function loadApi() {
gapi.client.load('fusiontables', 'v1', initialize);
}
function initialize() {
var isMobile = (navigator.userAgent.toLowerCase().indexOf('android') > -1) ||
(navigator.userAgent.match(/(iPod|iPhone|iPad|BlackBerry|Windows Phone|iemobile)/));
if (isMobile) {
var viewport = document.querySelector("meta[name=viewport]");
viewport.setAttribute('content', 'initial-scale=1.0, user-scalable=no');
}
var mapDiv = document.getElementById('googft-mapCanvas');
mapDiv.style.width = isMobile ? '100%' : '500px';
mapDiv.style.height = isMobile ? '100%' : '300px';
map = new google.maps.Map(mapDiv, {
center: new google.maps.LatLng(28.070831120253633, -82.434892289917),
zoom: 11,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
var query = 'select col2, col1 from 1-6pqmYvsmKGwt9IZcpIxFUmyYwmumoMAtMrE8pMe limit 1000';
var request = gapi.client.fusiontables.query.sqlGet({ sql: query });
request.execute(function(response) {
onDataFetched(response);
});
}
function onDataFetched(response) {
if (response.error) {
alert('Unable to fetch data. ' + response.error.message +
' (' + response.error.code + ')');
} else {
drawHeatmap(extractLocations(response.rows));
}
}
function extractLocations(rows) {
var locations = [];
for (var i = 0; i < rows.length; ++i) {
var row = rows[i];
if (row[0]) {
var lat = row[0];
var lng = row[1];
if (lat && lng && !isNaN(lat) && !isNaN(lng)) {
var latLng = new google.maps.LatLng(lat, lng);
locations.push(latLng);
}
}
}
return locations;
}
function drawHeatmap(locations) {
var heatmap = new google.maps.visualization.HeatmapLayer({
dissipating: true,
gradient: [
'rgba(102,255,0,0)',
'rgba(147,255,0,1)',
'rgba(193,255,0,1)',
'rgba(238,255,0,1)',
'rgba(244,227,0,1)',
'rgba(244,227,0,1)',
'rgba(249,198,0,1)',
'rgba(255,170,0,1)',
'rgba(255,113,0,1)',
'rgba(255,57,0,1)',
'rgba(255,0,0,1)'
],
opacity: 0.49,
radius: 20,
data: locations
});
heatmap.setMap(map);
}
google.maps.event.addDomListener(window, 'load', loadApi);
</script>
</head>
<body>
<div id="googft-mapCanvas"></div>
</body>
</html>

Implementing infinite animation in famousJS with StateModifier

I want a circle to act like a heart does, a pulsing animation. So the circle first scales to 75%, then to 100%. I want to make this an infinite loop.
Code:
var Engine = require('famous/core/Engine');
var Surface = require('famous/core/Surface');
var Transform = require('famous/core/Transform');
var StateModifier = require('famous/modifiers/StateModifier');
var Easing = require('famous/transitions/Easing');
var mainContext = Engine.createContext();
var surface = new Surface({
size: [180, 180],
properties: {
backgroundColor: 'grey',
borderRadius: '50%'
}
});
var stateModifier = new StateModifier();
stateModifier.setTransform(
Transform.scale(0.7, 0.7, 1),
{ duration : 1050 }
);
stateModifier.setTransform(
Transform.scale(1, 1, 1),
{ duration : 450 }
);
mainContext.add(stateModifier).add(surface);
Anyone knows how to implement this?
Use the callback and wrap the setTransform in a function to have each callback call each other when they finish.
Example running snippet
define('main', function(require, exports, module) {
var Engine = require('famous/core/Engine');
var Surface = require('famous/core/Surface');
var Transform = require('famous/core/Transform');
var StateModifier = require('famous/modifiers/StateModifier');
var Easing = require('famous/transitions/Easing');
var mainContext = Engine.createContext();
var surface = new Surface({
size: [180, 180],
properties: {
backgroundColor: 'grey',
borderRadius: '50%'
}
});
var stateModifier = new StateModifier();
function min() {
stateModifier.setTransform(
Transform.scale(0.7, 0.7, 1), {
duration: 1050
},
max
);
}
function max() {
stateModifier.setTransform(
Transform.scale(1, 1, 1), {
duration: 450
},
min
);
}
mainContext.add(stateModifier).add(surface);
surface.on('deploy', function() {
min();
});
});
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>

No lines drawn when drawing Polyline with MVCArray, with API v3.16 and later

If you use Google Maps API v3.16 and later, polyline are not drawn when a new marker is added to the polyline path and MVCArray, only markers plotted on a map.
My program based on code from http://nettique.free.fr/gmap/toolbar.html
html file :
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>map toolbar implementation</title>
<script type="text/javascript" src="http://maps.google.com/maps/api/js?v=3.exp&sensor=true"></script>
<style type="text/css">
--- truncate ----
</style>
<script type="text/javascript" src="toolbarv3_files/mapToolbar.js"></script>
<script type="text/javascript">
// Register an event listener to fire when the page finishes loading.
google.maps.event.addDomListener(window, 'load', initialize);
</script>
</head>
body section
drawing toolbar :
<div id="hand_b" onclick="MapToolbar.stopEditing()"/>
<div id="line_b" onclick="MapToolbar.initFeature('line')"/>
canvas :
<div id="map" style="width: 85%; height: 100%; position: absolute;"></div>
script file (mapToolbar.js):
var map;
var MapToolbar = {
//reorder index of a poly markers array
reindex:function(markers){
markers.forEach(function(marker, index){
marker.index = index;
});
},
//add a point to a poly, 'e' can be a click event or a latLng object
addPoint : function(e, poly, index) {
var e = (typeof e.latLng != "undefined")? e.latLng : e,
image = new google.maps.MarkerImage('images/marker-edition.png',
new google.maps.Size(9, 9),
new google.maps.Point(0, 0),
new google.maps.Point(5, 5)),
imageover = new google.maps.MarkerImage('images/marker-edition-over.png',
new google.maps.Size(9, 9),
new google.maps.Point(0, 0),
new google.maps.Point(5, 5)),
path = poly.getPath(),
index = (typeof index != "undefined")? index : path.length,
markers = (poly.markers)? poly.markers : new google.maps.MVCArray,
marker = new google.maps.Marker({
position: e,
map: map,
draggable: true,
icon: image
});
marker.index = index;
path.insertAt(index, e);
markers.insertAt(index, marker)
if(arguments[2]){
MapToolbar.reindex(markers);
}
features:{
.....
lineTab: {},
.....
},
//instanciate a new Feature instance and create a reference
initFeature: function(type){
new MapToolbar.Feature(type);
},
//check if a toolbar button is selected
isSelected: function(el){
return (el.className == "selected");
},
//the map DOM node container
....
lineCounter:0,
....
//select hand button
stopEditing: function() {
this.removeClickEvent();
this.select("hand_b");
},
//create new polyline function
MapToolbar.Feature.prototype.poly = function(type) {
var color = MapToolbar.getColor(false),
path = new google.maps.MVCArray,
poly,
self = this,
el = type + "_b";
if(type=="shape"){
poly = self.createShape( {strokeWeight: 3, fillColor: color}, path );
}else if(type=="line"){
poly = self.createLine( {strokeWeight: 3, strokeColor: color }, path );
}
poly.markers = new google.maps.MVCArray;
if(MapToolbar.isSelected(document.getElementById(el))) return;
MapToolbar.select(el);
MapToolbar.currentFeature = poly;
poly.setMap(map);
if(!poly.$el){
++MapToolbar[type+"Counter"];
poly.id = type + '_'+ MapToolbar[type+"Counter"];
poly.$el = MapToolbar.addFeatureEntry(poly.id, color);
MapToolbar.features[type+"Tab"][poly.id] = poly;
}
}
MapToolbar.Feature.prototype.createLine = function(opts, path) {
var poly = new google.maps.Polyline({
strokeWeight: opts.strokeWeight,
strokeColor: opts.strokeColor
}), self = this;
poly.setPath(new google.maps.MVCArray(path));
return poly;
}
//initialization function
function initialize(container) {
var options = {
mapTypeControlOptions: {
mapTypeIds: [google.maps.MapTypeId.ROADMAP, google.maps.MapTypeId.TERRAIN],
style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
}
}
map = new google.maps.Map(document.getElementById('map'));
map.setCenter(new google.maps.LatLng(47.9, 1.9 ));
map.setZoom(12);
map.setMapTypeId( google.maps.MapTypeId.ROADMAP );
with(MapToolbar){
with(buttons){
.....
$hand = document.getElementById("hand_b");
$line = document.getElementById("line_b");
....
}
....
select("hand_b");
}
MapToolbar.polyClickEvent = google.maps.event.addListener(map, 'click', function(event){
if( !MapToolbar.isSelected(MapToolbar.buttons.$shape) && !MapToolbar.isSelected(MapToolbar.buttons.$line) ) return;
if(MapToolbar.currentFeature){
MapToolbar.addPoint(event, MapToolbar.currentFeature);
}
});
}
complete version of "mapToolbar.js" script file is also available at : https://code.google.com/p/js2shapefile/source/browse/trunk/lib/mapToolbar.js?r=2
an error occurred when executing line "path.insertAt(index, e);" (addPoint function).
TypeError: this.j[qd] is not a function
...his[gd](a,b)}};L.insertAt=function(a,b){this.j[qd](a,0,b);bg(this);S[n](this,"in...
{main,g...try}.js (line 26, col 1473)
I had the same problem. I've solved changing poly.setPath in createLine function.
MapToolbar.Feature.prototype.createLine = function(opts, path) {
var poly = new google.maps.Polyline({
strokeWeight: opts.strokeWeight,
strokeColor: opts.strokeColor
}), self = this;
// 27/08/2014 - This not work
//poly.setPath(new google.maps.MVCArray(path));
poly.setPath(path);
return poly;
}

How to utilize google map MarkerCluster to catch Polygon rather than marker ?

everyone!
How to utilize google map MarkerCluster to catch Polygon rather than Marker ?
My program has about 20,000 markers on Google Map, and it becomes very slow when the data is loading into the map. Then I use JS code to draw one polygon as the replacement of marker. It would run faster. Maybe the PNG image loading for markers exercises negative influence on speed.
Finally, I read this article
http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/docs/examples.html
The function 'MarkerCluster' is great. However, it can be only used on the aspect of Google Marker.
var markerClusterer = new MarkerClusterer(map, **markerArray**)
So is there some solution for putting polygon into this cluster mechanism ?
Any help would be greatly appreciated !
I tentatively made an example.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=false"></script>
<script src="http://google-maps-utility-library-v3.googlecode.com/svn/trunk/markerclusterer/src/markerclusterer.js"></script>
<style>
html, body, #map_canvas {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
</style>
<script type='text/javascript'>
var mapCanvas;
function initalize() {
// Creating a map
var mapDiv = document.getElementById("map_canvas");
mapCanvas = new google.maps.Map(mapDiv, {
mapTypeId : google.maps.MapTypeId.ROADMAP
});
// Generate bunch of path data
var sw = new google.maps.LatLng(-19.448292, -152.012329);
var ne = new google.maps.LatLng(76.150236, 58.925171);
var bounds = new google.maps.LatLngBounds(sw, ne);
mapCanvas.setCenter(bounds.getCenter());
mapCanvas.setZoom(3);
var baseLat, baseLng, category, json = [], path;
for (var i = 0; i < 100; i++) {
baseLat = Math.random() * (ne.lat() - sw.lat()) + sw.lat();
baseLng = Math.random() * (ne.lng() - sw.lng()) + sw.lng();
path = [
new google.maps.LatLng(baseLat, baseLng),
new google.maps.LatLng(baseLat + 1, baseLng + 1),
new google.maps.LatLng(baseLat, baseLng + 2)
];
json.push(path);
}
var bounds, polyList = [];
for (var i = 0, length = json.length; i < length; i++) {
var polyline = createPolygon(json[i]);
polyList.push(polyline);
}
var clusterer = new MarkerClusterer(mapCanvas, polyList);
}
function createPolygon(path) {
var polygon = new google.maps.Polygon({
path : path,
strokeOpacity : 1,
strokeColor : "red"
});
var lastPath = null,
lastCenter = null;
polygon.getPosition = function() {
var path = this.getPath();
if (lastPath == path) {
return lastCenter;
}
lastPath = path;
var bounds = new google.maps.LatLngBounds();
path.forEach(function(latlng, i) {
bounds.extend(latlng);
});
lastCenter = bounds.getCenter()
return lastCenter;
};
return polygon;
}
google.maps.event.addDomListener(window, "load", initalize);
</script>
</head>
<body>
<div id="map_canvas"></div>
</body>
</html>

Resources