can anyone help me. when i using this code. the local server doesnt show anything. how to get points on the one map? thanks.
<script language="JavaScript" type="text/JavaScript">
//add map with defined center location and zoom level
var centerPoint = "21090.3965989332,40152.827324621125"
var levelNumber = 1;
var pointers="29320.30692133441,29190.96332578225|29520.30692133441,29190.96332578225:http://www.onemap.sg/icons/Hotels/hotel.gif|29420.30692133441,29190.96332578225:D1"
var OneMap = new GetOneMap('divMain', 'SM', { level: levelNumber, center: centerPoint, points: pointers});
//dojo.require("esri.map");
//dojo.require("esri.tasks.geometry");
//dojo.require("esri.layers.graphics");
//dojo.addOnLoad(initialize);
var search = 'txtSearchText';
function GetCurrentLevel() {
alert("Current Level:" + OneMap.map.getLevel())
}
</script>
<div id="divMain" style='width: 756px; height: 399px;'>
</div>
Related
I am trying to show a geodesic polygon on GoogleMaps. I thought it is enough to just add geodesic:true to polygon options. But it is displayed linearly despite its huge size. Am I doing it wrong or it is not supported ?
<html>
<head>
<script src="https://maps.google.com/maps/api/js?v=3"></script>
<script>
window.onload = function() {
var map = new google.maps.Map(document.body, {zoom:9,center:{lat:49.8,lng:18.2}});
new google.maps.Polygon({geodesic:true,map:map,
path:[{lat:50,lng:18},{lat:49.3,lng:18.5},{lat:50,lng:19}]});
}
</script>
</head>
<body style="position:absolute;width:99%;height:99%">
</body>
</html>
seems you are to centerd try move the polygon near pole
window.onload = function() {
var map = new google.maps.Map(document.body, {zoom:9,center:{lat:49.8,lng:18.2}});
new google.maps.Polygon({geodesic:true,map:map,
path:[{lat:70.0,lng:18.0},{lat:70.0,lng:22.5},{lat:50.0,lng:22.5},{lat:50.0,lng:18.0 ]} );
}
(and as suugestion use float ever)
I've got a Leaflet map with a single tile layer and then a LayerGroup (densityLayer) consisting of many (typically a few hundred) Rectangle layers, each of which is a semitransparent filled overlay with its fillColor based on population density for a particular year.
Based on a user action, the contents of densityLayer change. Pretty trivial to just run densityLayer.clearLayers() then generate all the new Rectangle layers and densityLayer.addLayer(aRectangle) for each of them.
What I want to do, though, is to animate a fade from the old to the new data: i.e., generate all the new Rectangle layers and put them in a new LayerGroup (newDensityLayer), and simultaneously fade out the original oldDensityLayer and fade in the newDensityLayer, and when the fade is complete, then clear out and remove oldDensityLayer and replace it with newDensityLayer.
My current solution is hideously inefficient:
var oldDensityLayer = densityLayer
var newDensityLayer = {...create new density layer here, add polygons, etc...}
oldDensityLayer.eachLayer(function(l) {
$(l._path).fadeOut(1000) // 1000ms animation time
})
setTimeout(function() {
oldDensityLayer.clearLayers()
myLeafletMap.removeLayer(oldDensityLayer)
oldDensityLayer = null
}, 1000)
myLeafletMap.addLayer(newDensityLayer)
// now fade in all the new polygons
newDensityLayer.eachLayer(function(l) {
$(l._path).hide() // so they start out invisible
$(l._path).fadeIn(1000)
})
densityLayer = newDensityLayer
This basically works, but gets pretty choppy and slow on anything but a very fast machine.
Is there some way to fade in/out an entire LayerGroup, or perhaps some option I haven't considered...?
This is critical functionality, so if adding another js library would help, that's fine. Also, SVG-specific answers are fine, as that's what I've got Leaflet using for its drawing functions, and cross-browser compatibility isn't a concern in this application.
Is there some way to fade in/out an entire LayerGroup, or perhaps some option I haven't considered...?
There is, in fact, an option which you haven't considered: manipulate the L.Renderer which actually draws the geometries as an HTML element. This means manipulating the actual <canvas> of a L.Canvas, or the actual <svg> of a L.SVG.
Remember any subclass of L.Path (Polygons, Polylines and such) can have its own renderer. Leaflet, by default, creates just one instance of L.Renderer and reuses it in all L.Paths unless told otherwise - this means less HTML elements and (in 99% of use cases) better performance.
So it should look something like:
var rendererA = L.canvas();
var rendererB = L.canvas();
var groupA = L.layerGroup().addTo(map);
var layerA1 = L.polygon(…, {renderer: rendererA}).addTo(groupA);
var layerA2 = L.polygon(…, {renderer: rendererA}).addTo(groupA);
var groupB = L.layerGroup().addTo(map);
var layerB1 = L.polygon(…, {renderer: rendererB}).addTo(groupB);
var layerB2 = L.polygon(…, {renderer: rendererB}).addTo(groupB);
// Here comes the magic - using the *undocumented*, *private* _container
// property of L.Canvas to access the <canvas> HTML element itself
rendererA._container.style.opacity = 0.5;
The code is obviously incomplete, but it should illustrate the idea properly.
That will create two different <canvas> in the browser, and changing the opacity of the HTML element itself will bypass re-rendering the features. There should be an analogous solution using L.SVG instead, but I'm not sure how browsers composite the opacity of SVG containers.
There are obvious disadvantages for this method - like losing any z-ordering (bringToFront, etc) if geometries from both groups should be intertwined.
Also, please remember: Using undocumented, private properties of leaflet objects is not recommended unless you really really really know what you're doing and are willing to see your code break in API changes or rare circumstances.
You could include an SVG layer populated with your shapes. Below in an example that fades out 500 svg shapes, then builds a new bunch of SVG shapes and fades them in. (Edited to zoom shapes at their locations)
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Fade Out/In SVG Elements in Leaflet World Map</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src='https://api.tiles.mapbox.com/mapbox.js/v2.1.5/mapbox.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox.js/v2.1.5/mapbox.css' rel='stylesheet' />
</head>
<body style='font-family:arial'>
<center><h4>Fade Out/In SVG Elements in Leaflet World Map</h4>
<div style='width:90%;background-color:gainsboro;text-align:justify;padding:10px;border-radius:6px;'>
This adds 500 svg elements(circles, ellipses, rects, polygons) to the SVG layer in the world map. The map's mouse wheel zoom remains smooth in IE/CH/FF. Each element has a lat/lng value, converted to the needed x,y values to translate each symbol to the desired point.
During map zoom level changes, the symbols are automatically scaled and translated, maintaining their original size and position.
</div>
<br />
<table border=1>
<tr>
<td>
<b>Scenerio:</b><br />
1). The map is placed into its DIV (width:800px, height:400px).<br />
2). The map is centered at Lat/Lng (0,0) at zoom level 1.<br />
3.) The SVG element is added via <b>initPathRoot.</b><br />
4.) 500 SVG elements are added, randomly place about the world.<br />
5.) The svg <b>viewBox</b> is computed, used to create x,y values for the symbols.<br />
6.)Each element is translated/scaled when the map is zoomed, using the <b>viewreset</b> event.<br /> This calls the map method <b>latLngToLayerPoint(MyLatLng)</b> to accomplish this.
<br>7.) Select <button>fade out/in</button> to fade out the current elements, build a new group, then fade In new group
</td>
</tr>
</table>
<div style='width:800px;height:400px' id='MyMap'></div>
<button onClick=fadeOutIn()>fade out/in</button>
<br />Javascript:<br />
<textarea spellcheck=false id=jsValue style='border-radius:26px;font-size:110%;font-weight:bold;color:midnightblue;padding:16px;background-color:beige;border-width:0px;font-size:100%;font-family:lucida console;width:90%;height:400px'></textarea>
</center>
<script id=myScript>
L.mapbox.accessToken = 'pk.eyJ1IjoiZmhlbXNoZXIiLCJhIjoiODQ5MW9WayJ9.px2P6wVMFucfXHE1zmDA1A';
MyMap = L.mapbox.map('MyMap', 'mapbox.streets', { zoomControl:false,center: new L.latLng(0,0),zoom:1,minZoom:1});
//---zooming the map---
MyMap.on("viewreset", adjustSVGSymbols);
var MySVG
var SymbolG //---<g> element containing all symbols---
var VBw
var VBh
var NS="http://www.w3.org/2000/svg"
//---body onload---
function initSVG()
{
MyMap._initPathRoot() //---creates an svg layer---
MySVG=document.querySelector("svg") //---access svg element---
//---place symbols in here---
SymbolG=document.createElementNS(NS,"g")
SymbolG.setAttribute("id","symbolG")
MySVG.appendChild(SymbolG)
//---create random svg elements, place in SymbolG--
getViewBox()//---used to place svg random elements
//---create 500 symbols at size 10 pixels--
svgGLOB(500,10)
}
//--- on map zoom - fired via map event: viewreset---
function adjustSVGSymbols()
{
var symbols=SymbolG.childNodes
for(var k=0;k<symbols.length;k++)
{
var symbol=symbols.item(k)
//---initial lat/lng for symbol---
var lat=parseFloat(symbol.getAttribute("lat"))
var lng=parseFloat(symbol.getAttribute("lng"))
var latLng= new L.latLng(lat, lng)
var transX=MyMap.latLngToLayerPoint(latLng).x
var transY=MyMap.latLngToLayerPoint(latLng).y
//---scale---
var initZoom=parseFloat(symbol.getAttribute("initZoom"))
var scale = (Math.pow(2, MyMap.getZoom())/2)/(Math.pow(2, initZoom)/2);
//---trash previous transform---
symbol.setAttribute("transform","")
symbol.removeAttribute("transform")
var transformRequestObj=MySVG.createSVGTransform()
var animTransformList=symbol.transform
//---get baseVal to access/place object transforms
var transformList=animTransformList.baseVal
//---translate----
transformRequestObj.setTranslate(transX,transY)
transformList.appendItem(transformRequestObj)
transformList.consolidate()
//---scale---
transformRequestObj.setScale(scale,scale)
transformList.appendItem(transformRequestObj)
transformList.consolidate()
}
}
//---needed for random symbol placement: create x,y values---
function getViewBox()
{
vb=MySVG.viewBox.baseVal
VBw=vb.width
VBh=vb.height
}
//---compute svg elems: circles, rects, ellipses, polygons---
function svgGLOB(elems,elemSize)
{
//---note: each browser creates a different sized svg layer---
var svgWidth=VBw
var svgHeight=VBh
//---obtain a random whole number from a thru b---
function rdm(a,b)
{
return a + Math.floor(Math.random()*(b-a+1));
}
function randomPoints(elems,svgWidth,svgHeight,elemSize)
{
//--return format:[ [x,y],[x,y],,, ]
//---Generate random points---
function times(n, fn)
{
var a = [], i;
for (i = 0; i < n; i++)
{
a.push(fn(i));
}
return a;
}
var width=svgWidth-2*elemSize //---offset from edge---
var height=svgHeight-2*elemSize //---offset from edge---
return RandomPnts = times(elems, function() { return [Math.floor(width * Math.random()) + elemSize, Math.floor(height * Math.random()) + elemSize] });
}
//---random color---
function rcolor()
{
var letters = '0123456789ABCDEF'.split('');
var color = '#';
for (var i = 0; i < 6; i++ )
{
color += letters[Math.round(Math.random() * 15)];
}
return color;
}
function polygon(vCnt,radius,centerX,centerY)
{
var myPoints=[]
var polyXPts = Array(vCnt);
var polyYPts = Array(vCnt);
var vertexAngle = 360/vCnt;
//---init polygon points processor---
for(var v=0; v<vCnt; v++)
{
theAngle = (v*vertexAngle)*Math.PI/180;
polyXPts[v] = radius*Math.cos(theAngle);
polyYPts[v] = -radius*Math.sin(theAngle);
}
//--note points are CCW---
for(var v=0;v<vCnt; v++)
{
var point=[centerX+polyXPts[v],centerY+polyYPts[v]]
myPoints.push(point)
}
return myPoints
}
var Points=randomPoints(elems,svgWidth,svgHeight,elemSize)
var n=Points.length
var circleCnt=0
var ellipseCnt=0
var rectCnt=0
var polygonCnt=0
var RandomElems=[]
RandomElems[0]="circle"
RandomElems[1]="rect"
RandomElems[2]="ellipse"
RandomElems[3]="polygon_3"
RandomElems[4]="polygon_4"
RandomElems[5]="polygon_5"
RandomElems[6]="polygon_6"
RandomElems[7]="polygon_7"
RandomElems[8]="polygon_8"
RandomElems[9]="polygon_9"
RandomElems[10]="polygon_10"
RandomElems[11]="polygon_11"
RandomElems[12]="polygon_12"
//---create all at center(0,0), then translate---
for(var k=0;k<n;k++)
{
var rand=rdm(0,12)
var elemStr=RandomElems[rand]
if(!elemStr.indexOf("_"))
var elemSt=elemStr
else
var elemSt=elemStr.split("_")[0]
//var elem=document.createElementNS(NS,elemSt)
var x=Points[k][0]
var y=Points[k][1]
var lng=((x * 360 / VBw) - 180)
var lat= (90 - (y * 180 / VBh))
var id="symbol"+k
var fill=rcolor()
var elem=document.createElementNS(NS,elemSt)
elem.setAttribute("id",id)
elem.setAttribute("cursor","default")
elem.setAttribute("fill",fill)
elem.setAttribute("lat",lat)
elem.setAttribute("lng",lng)
if(elemSt=="circle")
{
var r=elemSize
elem.setAttribute("r",r)
}
else if(elemSt=="ellipse")
{
var rx=elemSize
var ry=elemSize/2
elem.setAttribute("rx",rx)
elem.setAttribute("ry",ry)
}
else if(elemSt=="rect")
{
var width=elemSize
var height=elemSize
//---center at 0,0---
var x=-elemSize/2
var y=-elemSize/2
elem.setAttribute("width",width)
elem.setAttribute("height",height)
elem.setAttribute("x",x)
elem.setAttribute("y",y)
}
else if(elemSt=="polygon")
{
var pgonSides=parseInt(elemStr.split("_")[1])
var pgonPnts=polygon(pgonSides,elemSize,0,0)
var points=pgonPnts.join()
elem.setAttribute("points",points)
}
elem.setAttribute("initZoom",1)
SymbolG.appendChild(elem)
}
//---initialize locations---
adjustSVGSymbols()
}
//---fade out/In button----
function fadeOutIn()
{
$("#symbolG").fadeOut(1000, function(){
createAnotherGlob()
});
}
function createAnotherGlob()
{
var symbols=SymbolG.childNodes
for(var k=symbols.length-1;k>=0;k--)
SymbolG.removeChild(symbols.item(k))
svgGLOB(500,10,true)
$("#symbolG").fadeIn(1500)
}
</script>
<script>
document.addEventListener("onload",init(),false)
function init()
{
jsValue.value=myScript.text
initSVG()
}
</script>
</body>
</html>
I've been asked to modify some JavaScript code that looks something like this:
<html>
<head>
<script>
var text1="foo";
var text2="bar"
</script>
<script src="/process.js"></script>
</head>
<body>
<div id="container"></div>
</body>
</html>
This code takes inputs text1 & text2, does some image processing, and displays the resulting image in the div in the body. How can I modify it so that the JavaScript library can be called multiple times on different input values on the same HTML page, something (in effect) like the following:
<html>
<head>
<script>
var image_width=100;
var image_height=200;
</script>
<script>
var image_width=50;
var image_height=150;
</script>
<script src="/process.js"></script>
</head>
<body>
<div id="container"></div>
<div id="container"></div>
</body>
</html>
The code in process.js is something like this:
var cc1 = $('#canvas_container');
var ctx1 = cc1[0].getContext('2d');
function make_image(){
$('#container').width(image_width);
$('#container').height(image_height);
var cntnr = document.getElementById('container');
var c1 = document.createElement("canvas");
c1.width = image_width;
c1.height = image_height;
c1.id = "canvas_container";
cntnr.appendChild(c1);
// image generation code here
}
Thanks for your help!
(EDIT: wasn't this a Google Maps question, yesterday? If not, I should give another example)
Let me just show you how you can use parameters in functions.
Your example:
So, process.js contains the functions. Calling those functions, you do outside that file.
Notice: Your example doesn't show anything visible on the screen. But the two canvas elements are there.
The point is: anything that isn't general for all instances, you should put in a parameter.
index.php
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="process.js"></script>
<script>
window.onload = function() { // do this so the script waits until the page is loaded
// image1
make_image('container1', 'canvas1', 100, 200);
// image2
make_image('container2', 'canvas2', 50, 150);
}
</script>
</head>
<body>
<div id="container1"></div>
<div id="container2"></div>
</body>
</html>
process.js
function make_image(container, canvas_id, width, height) {
$('#' + container).width(width);
$('#' + container).height(height);
var cntnr = document.getElementById(container);
var c1 = document.createElement("canvas");
c1.width = width;
c1.height = height;
c1.id = canvas_id;
cntnr.appendChild(c1);
// image generation code here
}
Google Maps example
So, anything about initialize() that is specific to 1 map, must be set in the parameters. Example: if you want a different zoom on map1/map2, put another parameter 'zoom', next to lng, and call one with zoom 18, one with zoom 15. Try it out.
<!doctype html>
<html>
<head>
<style>
#container1, #container2 {
width: 500px;
height: 400px;
margin-bottom: 20px;
}
</style>
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script>
// http://stackoverflow.com/questions/30996197/how-to-pass-parameters-to-a-javascript-library-and-how-to-call-it-multiple-times?noredirect=1#comment50061772_30996197
// gets triggered twice, by page_is_loaded()
function initialize(container_id, lat, lng) {
var myLatlng = new google.maps.LatLng(lat, lng);
var mapProp = {
center: myLatlng,
zoom: 17,
mapTypeId:google.maps.MapTypeId.HYBRID
};
var map=new google.maps.Map(document.getElementById(container_id),mapProp);
return map; // by doing this, who ever calls this function has the map object, to do what ever one wants.
}
// gets triggered when the page is loaded
function page_is_loaded() {
var map1 = initialize('container1', 50.89515421660153, 4.341372907161713); // Atomium, Brussels, Belgium
var map2 = initialize('container2', 53.34184485510149, -6.286933958530426); // Guinness Storehouse, Dublin, Irish Republic
// let's put a marker on map1, at the atomium, on the parking lot, where I left my car
var marker_atomium = new google.maps.Marker({
position: new google.maps.LatLng(50.895783519434076, 4.339616060256958),
map: map1
});
}
// this triggers page_is_loaded(), to be triggered when the DOM of the page is loaded
google.maps.event.addDomListener(window, 'load', page_is_loaded);
</script>
</head>
<body>
<div id="container1"></div>
<div id="container2"></div>
</body>
</html>
I am using the Geolocation Marker Script from the Google Maps Utilities Library V3 in order to display the position of a user.
What I want to achieve (I am a newbie to the Google Maps API!) is:
have the users current coordinates displayed (e.g. in a simple CSS container somewhere on the page)
connect an event to a marker. I should be triggered when the user is close.
Appreciate your help!
To display coordinates to the user, you would need a reference to a DOM Element. Then it's a simple matter of updating the content.
HTML On the Page
<div id="UserCoordinates">Waiting on GPS Position ...</div>
In Script
google.maps.event.addListener(GeoMarker, 'position_changed', function() {
var UserPosition = this.getPosition();
var DisplayElement = document.getElementById('UserCoordinates');
if(UserPosition === null) {
DisplayElement.innerHTML = 'Waiting on GPS Position...';
} else {
DisplayElement.innerHTML =
'Current Position: ' + UserPosition.toUrlValue();
}
});
This will show the user their current position as it changes. If you are going to continue using a full screen map, you'll probably want to implement the UserCoordinates div as a map control. The API Reference has a good overview and multiple examples on this.
Display an info window when the user is within X meters of a location
This is a little tricky because there are multiple scenarios to handle and you don't want the infowindow opening repeatedly as they move within your radius.
Distance calculation
I see you have a distance function in your code, but I recommend using the one in the Spherical Geometry library of the API. You just have to specifically load the library with your api script tag:
<script type="text/javascript"
src="https://maps.googleapis.com/maps/api/js?libraries=geometry&sensor=true_or_false">
</script>
Then you need to add to the position_changed event handler:
var IsWithinRadius = false; //assume they start outside of the circle
var RadiusInMeters = 1000; //within 1 km
var LocationOfInterest = map.getCenter();
google.maps.event.addListener(GeoMarker, 'position_changed', function() {
var UserPosition = this.getPosition();
var DisplayElement = document.getElementById('UserCoordinates');
if(UserPosition === null) {
DisplayElement.innerHTML = 'Waiting on GPS Position...';
IsWithinRadius = false; //you don't know where they are
} else {
DisplayElement.innerHTML =
'Current Position: ' + UserPosition.toUrlValue();
var IsCurrentPositionInRadius =
Math.abs(google.maps.geometry.spherical.computeDistanceBetween(
UserPosition, LocationOfInterest)) <= RadiusInMeters;
var JustEnteredRadius = !IsWithinRadius && IsCurrentPositionInRadius;
IsWithinRadius = IsCurrentPositionInRadius;
if(JustEnteredRadius) {
//trigger action here.
alert("Within raidus");
}
}
});
I have GPS tracking server and problem with clearing markers added with MarkerManager from database. My truncated code:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
<head>
<script src='http://maps.google.com/maps?file=api&v=2&hl=pl&key=my_key' type='text/javascript'></script>
</head>
<body onload='mapStart()' onunload='GUnload()'>
<script type='text/javascript'>
var map;
var mgr=false;
var timeOut=null;
function mapStart()
{
if(GBrowserIsCompatible())
{
map = new GMap2(document.getElementById("map"),{mapTypes: [G_NORMAL_MAP,G_HYBRID_MAP,G_SATELLITE_MAP,G_PHYSICAL_MAP]});
center = new GLatLng(52.536395, 13.42534);
map.setCenter(center, 6);
mgr = new GMarkerManager(map,{maxZoom: 19});
refreshMarkers();
}
}
function refreshMarkers()
{
clearTimeout(timeOut);
GDownloadUrl('dane2.php', function(dane,respCode)
{
if(respCode==200)
{
var xml = GXml.parse(dane);
var marker = dodajMarker(arguments, 15, 15);
}
else
{
alert('Cant open dane2.php');
}
});
mgr.clearMarkers(); // ???
timeOut=setInterval("refreshMarkers()",2000);
}
function dodajMarker(arguments, minZoom, maxZoom)
{
var ikona = new GIcon();
ikona.image = 'http://www.google.com/intl/en_ALL/mapfiles/dd-start.png';
ikona.iconSize = new GSize(20, 34);
ikona.iconAnchor = new GPoint(10, 34);
var marker = new GMarker(new GLatLng(latitude,longitude),{icon: ikona});
mgr.addMarker(marker,minZoom,maxZoom);
return marker;
}
</script>
<div id="map" style="align: center; width: 1000px; height: 490px; solid black; background: gray;"></div>
</body>
</html>
My page: http://m2mgsm.com/gps/index.php You can login: "admin", password: "12345" Click Test Map ("Mapatesty" - polish language only, english soon) in menu and then Select IMEI ("Wybierz IMEI") e.g. 355832010123229 and check Route ("Pokaż trasę:") and From/To ("Od/Do") date (e.g. 05.01.2012/05.01.2012) and "Filtruj". You can now view source of my map script in frame. I want to refresh ONLY markers with e.g. 3 sec. interval and it works, but new markers are OVERLAY on old markers...
Ps. Sorry for my English.
You have errors is your JS:
ReferenceError: kontener is not defined [http://m2mgsm.com/gps/mapatesty.php:259]
TypeError: Object #<yv> has no method 'clearMarkers' [http://m2mgsm.com/gps/mapatesty.php:459]
Try to use Firefox with Firebug extension or Chrome with its built-in Debugger to trace through your JavaScript code and eliminate the bugs.