Google Maps API v2: MarkerManager clearMarkers(); doesn't work - javascript

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.

Related

Stumped completely by "UncaughtReferenceError: X not defined at function"

I am trying to build a google map that takes data from a fusion table using their api and displays it on the map. I have the data displaying on the map now.
I would like to have a button that toggles the data on/off and after googling extensively I have tried to implement the solutions I found. I have the code set up almost exactly the same but am still unable to toggle the data.
I believe something is wrong with my scope because whenever I click the button it gives a "Uncaught ReferenceError: view1 is not defined" error in the Javascript Dev Console .
I have googled this as well and at first I believed that the function "toggleView1" was not defined globally so I changed it, however it still will not work... Any suggestions would be greatly appreciated, I am at a loss at this point.
<!DOCTYPE html>
<html>
<head>
<title>WorkingMapTiles</title>
<meta charset="utf-8"/>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no"/>
<script src="https://maps.google.com/maps/api/js?key=XXXAPIKEYXX">. </script>
<script>
var view1 = new google.maps.FusionTablesLayer({
query: {
select: '\'LatitudeLongitude\'',
from: 'XXXfusionTableIdXXX'
}
});
function init() {
var mapBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(45.000, -65.000),
new google.maps.LatLng(46.000, -64.000));
var mapMinZoom = 14;
var mapMaxZoom = 17;
var map = new google.maps.Map(document.getElementById("map"));
map.fitBounds(mapBounds);
view1.setMap(map);
}
////FUNCTION NOT GETTING TRIGGERED BY BUTTONS
function toggleView1() {
if(view1.map) {
view1.setOptions({map: null});
} else {
view1.setOptions({map: map});
}
}
</script>
<style>
html, body, #map { width:100%; height:100%; margin:0; padding:0; }
#floating-panel { position: absolute; top: 10px; left: 25%;}
</style>
</head>
<body onload="init()">
<div id="map"></div>
<div id="floating-panel">
<input type="button" value="Toggle view1" onclick="toggleView1();">. </input>
</div>
</body>
</html>
Originaly:
function init() {
var mapBounds = new google.maps.LatLngBounds(
new google.maps.LatLng(45.000, -65.000),
new google.maps.LatLng(46.000, -64.000));
var mapMinZoom = 14;
var mapMaxZoom = 17;
var map = new google.maps.Map(document.getElementById("map"));
map.fitBounds(mapBounds);
var view1 = new google.maps.FusionTablesLayer({
query: {
from: 'XXXfusionTableIdXXX'
}
});
view1.setMap(map);
}
View one is in init()'s scope because that is where is defined. Brought variable definition of view1 out of init()'s scope. Note that you may not have another definition of view1 inside of init()'s scope or there will be variable shadowing

onemap api doesnt show points

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>

How to pass parameters to a JavaScript library and how to call it multiple times with different input sets on the same web page

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>

ArcGIS Javascript API - addLayers

I working on a project trying to add feature layers from ArcGIS online to a web map application using the JavaScript API where a user can toggle the layers on and off through a HTML tick box. The layers are importing correctly and are displayed when the tick boxes are bypassed but I can get it to work with the tickboxes. I have hacked code from ArcGIS samples etc so it must be some small thing I keep missing!
Here is the code - basically all I want is the layers to toggle on and off on top of a constant base map based on which checkboxes the user ticks on and off
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!--The viewport meta tag is used to improve the presentation and behavior of the samples
on iOS devices-->
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
<title>Select with feature layer</title>
<link rel="stylesheet" href="http://js.arcgis.com/3.10/js/dojo/dijit/themes/tundra/tundra.css">
<link rel="stylesheet" href="http://js.arcgis.com/3.10/js/esri/css/esri.css">
<style>
html, body, #mapDiv {
padding: 0;
margin: 0;
height: 100%;
}
#messages{
background-color: #fff;
box-shadow: 0 0 5px #888;
font-size: 1.1em;
max-width: 15em;
padding: 0.5em;
position: absolute;
right: 20px;
top: 20px;
z-index: 40;
}
</style>
<script src="http://js.arcgis.com/3.10/"></script>
<script>
var map;
require([
"esri/map", "esri/layers/FeatureLayer",
"esri/tasks/query", "esri/geometry/Circle",
"esri/graphic", "esri/InfoTemplate", "esri/symbols/SimpleMarkerSymbol",
"esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol", "esri/renderers/SimpleRenderer",
"esri/config", "esri/Color", "dojo/dom", "dojo/domReady!", "dojo/on", "dojo/query", "dojo/domReady!", "esri/layers/ArcGISDynamicMapServiceLayer", "esri/layers/ImageParameters",
], function (
Map, FeatureLayer,
Query, Circle,
Graphic, InfoTemplate, SimpleMarkerSymbol,
SimpleLineSymbol, SimpleFillSymbol, SimpleRenderer,
esriConfig, Color, dom, on, query, ArcGISDynamicMapServiceLayer, ImageParameters
) {
// use a proxy page if a URL generated by this page is greater than 2000 characters
//
// this should not be needed as nearly all query & select functions are performed on the client
esriConfig.defaults.io.proxyUrl = "/proxy";
map = new Map("mapDiv", {
basemap: "streets",
center: [-120.303130, 36.542750],
zoom: 5,
slider: false
});
//add the census block points in on demand mode. Note that an info template has been defined so when
//selected features are clicked a popup window will appear displaying the content defined in the info template.
var Offices = new FeatureLayer("URL", {
infoTemplate: new InfoTemplate("Block: ${BLOCK}", "${*}"),
outFields: ["*"]
});
var Northridge = new FeatureLayer("URL", {
infoTemplate: new InfoTemplate("Block: ${BLOCK}", "${*}"),
outFields: ["*"]
});
var Associates = new FeatureLayer("URL", {
infoTemplate: new InfoTemplate("Block: ${BLOCK}", "${*}"),
outFields: ["*"]
});
// selection symbol used to draw the selected census block points within the buffer polygon
var symbol = new SimpleMarkerSymbol(
SimpleMarkerSymbol.STYLE_CIRCLE,
12,
new SimpleLineSymbol(
SimpleLineSymbol.STYLE_NULL,
new Color([247, 34, 101, 0.9]),
1
),
new Color([207, 34, 171, 0.5])
);
Offices.setSelectionSymbol(symbol);
//make unselected features invisible
var nullSymbol = new SimpleMarkerSymbol().setSize(10);
var RedCircle = new SimpleMarkerSymbol().setSize(8);
Offices.setRenderer(new SimpleRenderer(nullSymbol));
on(dom.byId("layer0CheckBox"), "change", updateLayerVisibility);
on(dom.byId("layer1CheckBox"), "change", updateLayerVisibility);
on(dom.byId("layer2CheckBox"), "change", updateLayerVisibility);
function updateLayerVisibility() {
var inputs = query(".list_item");
var inputCount = inputs.length;
//in this application layer 2 is always on.
visibleLayerIds = [2];
for (var i = 0; i < inputCount; i++) {
if (inputs[i].checked) {
visibleLayerIds.push(inputs[i].value);
}
}
if (visibleLayerIds.length === 0) {
visibleLayerIds.push(-1);
}
map.addLayers(visibleLayerIds);
}
});
</script>
</head>
<body>
<br />
<br />
Layer List : <span id="layer_list"><input type='checkbox' class='list_item' id='layer0CheckBox' value="Northridge" />Earthquake
<input type='checkbox' class='list_item' id='layer1CheckBox' value="Offices" />Offices
<input type='checkbox' class='list_item' id='layer2CheckBox' value="Associates" />Associates
</span><br />
<br />
<div id="mapDiv"></div>
</body>
</html>
Done this long time ago
changeVLayerVisibility: function(names) {
Ext.Array.each(map.graphicsLayerIds, function(id) {
map.getLayer(id).setVisibility(names.indexOf(id) !== -1);
});
},
Check an example here: http://smart-tech-group.com/arcgismap/
The map-related logic is stored in http://smart-tech-group.com/arcgismap/APP/view/ArcMapViewer.js I was a js-newbie back then, so feel free to argue on my code style;)
In function updateLayerVisibility, the map.addLayers usage is wrong.
you should add featurelayers, graphic layers, dynamic layers or tiled layers, not the ids, unless you store them in the array visibleLayerIds.
You may consider use ArcGISDynamicMapServiceLayer to control visible layer ids. Then use setVisibleLayers API see https://developers.arcgis.com/javascript/jsapi/arcgisdynamicmapservicelayer-amd.html
FeatureLayer is usually for a single layer, use service like MapServer/2 or FeatureServer/2.

Get access to Google Maps API from a Chrome extension

Say I'd like to find addresses on any webpage and have a click on each one of them insert a small Google Maps below the address.
The problem I'm running into is that the GMaps library must be loaded via a < script> tag. But because anything loaded via < script> is out of the Chrome extension execution context, the "google.maps" object won't be available to my content scripts.
Any thoughts on a workaround?
What you could do is create an iframe that contains a page to your map viewer. Then you will belong in the context of Content Scripts and you have full access to Chrome's Message Passing.
Since I have created hundreds of extensions, I have done exactly this in tons of them, and some of them are available in my github.com/mohamedmansour page. I will show an example that I just did for this problem below, unfortunately it may contain bugs. Check my github page above for a more complete example.
What I would do
Create a map_viewer.html page in your extension.
Include within the <head> tag the <script src="http://maps.google.com/maps?file=api.....
Use Chrome Message Passing to pass data between content scripts.
For example
map_viewer.html
<!DOCTYPE html>
<html>
<head>
<link type="text/css" rel="stylesheet" href="/css/map_viewer.css" />
<script type="text/javascript" src="/js/map_viewer.js"></script>
</head>
<body>
<div id="map_canvas"></div>
</body>
</html>
map_viewer.js
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
if (request.method == 'RenderMap') {
renderMap(request.data.latitude, request.data.longitude);
}
});
function renderMap(latitude, latitude) {
var map = new GMap2(document.getElementById('map_canvas'));
map.setCenter(new GLatLng(latitude, latitude), 13);
var marker = new GMarker(new GPoint(lng, lat));
map.addOverlay(marker);
}
webpage_content_script.js
...
// Unique ID to differentiate this content script from the rest of the web.
// or use the extension id from ##__extension_id__, I recall there was a bug, haven't
// checked if it got resolved though.
var UNIQUE_MAP_VIEWER_ID = 'crx_myextension_iframe';
var latitude = -1;
var longitude = -1;
/**
* Here is where you want to render a latitude and longitude. We create an iframe so we
* we can inject it. We just want to maintain a single instance of it though.
*/
function onRenderMap() {
var mapViewerDOM = document.getElementById(UNIQUE_MAP_VIEWER_ID);
if (mapViewerDOM) {
mapViewerDOM.parentNode.removeChild(mapViewerDOM);
}
mapViewerDOM = document.createElement('iframe');
mapViewerDOM.setAttribute('id', UNIQUE_MAP_VIEWER_ID);
mapViewerDOM.setAttribute('src', chrome.extension.getURL('map_viewer.html');
mapViewerDOM.setAttribute('frameBorder', '0');
mapViewerDOM.setAttribute('width', '99.90%');
mapViewerDOM.setAttribute('height', '100%');
mapViewerDOM.setAttribute('style', 'position: fixed; top: 0; left: 0; overflow: hidden; z-index: 99999');
mapViewerDOM.onload = function(e) {
sendResponse({
method: 'RenderMap',
data: {
latitude: latitude,
longitude: longitude
}
});
}
document.body.appendChild(mapViewerDOM);
}
...
I hope this would steer you in the right direction.
Thanks,
Mohamed Mansour

Categories