OpenLayers: Null or undefined error in AddPopup - javascript

I get this error when I call map.AddPopup() in OpenLayers:
Unable to get value of the property 'Left'; object is null or undefined
http://www.openlayers.org/api/OpenLayers.js
The same error occurs in both Chrome and IE. The map works fine when I comment out that line, and the markers work fine as well. Later, icon0 and lonLat0 will be several items in a loop, but I'll handle that. The end result should be a text box of some kind that would display on the marker.
The marker at lonLat0 displays, so it doesn't seem like a problem with the lonLat object.
Yes, I will end up displaying many markers with text on them all at once. I know, it seems silly, but that's the requirement.
Why does addPopup give me this error?
<html><body>
<div id='mapdiv'></div> <script src='http://www.openlayers.org/api/OpenLayers.js'></script>
<script>
map = new OpenLayers.Map('mapdiv');
map.addLayer(new OpenLayers.Layer.OSM());
var lonLat = new OpenLayers.LonLat(-104.73,38.92).transform(new OpenLayers.Projection('EPSG:4326'), map.getProjectionObject() );
var markers = new OpenLayers.Layer.Markers( 'Markers' );
map.addLayer(markers);
markers.addMarker(new OpenLayers.Marker(lonLat));
function onPopupClose(evt) {selectControl.unselect(this.feature); }
var icon0 = new OpenLayers.Icon("pinMS.png", new OpenLayers.Size(32,32), new OpenLayers.Pixel(-16,-32));
var lonLat0 = new OpenLayers.LonLat(-104.73,38.92).transform(new OpenLayers.Projection('EPSG:4326'), map.getProjectionObject());
markers.addMarker(new OpenLayers.Marker(lonLat0, icon0.clone()));
// Error throws here
map.addPopup(new OpenLayers.Popup.FramedCloud("featurePopup", lonLat0, new OpenLayers.Size(10, 10), "<h2>Title</h2>description", null, true, onPopupClose));
map.setCenter (lonLat, 1);
</script></body></html>

I was able to reproduce your error and fix it. That demo code is really bad. I would start with a working example and modify it to fit your needs.
For example you need to call your javascript on <body onload="init()"> or else i'm surprised it even renders for you.
Anyway, All i did was replaced the map = new OpenLayers.Map('mapdiv'); for this:
map = new OpenLayers.Map({
div: "mapdiv",
center: new OpenLayers.LonLat(0, 0)
});
But here's the complete code incase you want to improve the structure of your file.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<meta name="apple-mobile-web-app-capable" content="yes">
<title>Open Popup on Layer.Vector</title>
<link rel="stylesheet" href="http://openlayers.org/dev/theme/default/style.css" type="text/css">
<link rel="stylesheet" href="http://openlayers.org/dev/examples/style.css" type="text/css">
<script src="http://www.openlayers.org/api/OpenLayers.js"></script>
<script type="text/javascript">
function init() {
map = new OpenLayers.Map({
div: "mapdiv",
center: new OpenLayers.LonLat(0, 0)
});
map.addLayer(new OpenLayers.Layer.OSM());
var lonLat = new OpenLayers.LonLat(-104.73, 38.92).transform(new OpenLayers.Projection('EPSG:4326'), map.getProjectionObject());
var markers = new OpenLayers.Layer.Markers('Markers');
map.addLayer(markers);
markers.addMarker(new OpenLayers.Marker(lonLat));
function onPopupClose(evt) { selectControl.unselect(this.feature); }
var icon0 = new OpenLayers.Icon("pinMS.png", new OpenLayers.Size(32, 32), new OpenLayers.Pixel(-16, -32));
var lonLat0 = new OpenLayers.LonLat(-104.73, 38.92).transform(new OpenLayers.Projection('EPSG:4326'), map.getProjectionObject());
markers.addMarker(new OpenLayers.Marker(lonLat0, icon0.clone()));
// Error throws here
map.addPopup(new OpenLayers.Popup.FramedCloud("featurePopup", lonLat0, new OpenLayers.Size(10, 10), "<h2>Title</h2>description", null, true, onPopupClose));
map.setCenter(lonLat, 1);
}
</script>
</head>
<body onload="init()">
<div id="mapdiv" class="smallmap"></div>
</body>
</html>

Related

Add Info Bubbles to Here Maps

how to add Info Bubbles to HERE maps. I follow the steps on the HERE api page, but the info bubble doesn't popup.
According to the Here api, here is the way to add popup.
https://developer.here.com/documentation/maps/topics/map-controls.html
var bubble = new H.ui.InfoBubble({ lng: 13.4, lat: 52.51 }, {
content: '<b>Hello World!</b>'
});
// Add info bubble to the UI:
ui.addBubble(bubble);
I follow the code and the map loads correctly with the right coordinates, but I don't see any info bubble on the map.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0,
width=device-width" />
<link rel="stylesheet" type="text/css" href="https://js.api.here.com/v3/3.0/mapsjs-ui.css?dp-version=1533195059" />
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-core.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-service.js"></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>
<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 src="http://js.api.here.com/v3/3.0/mapsjs-ui.js" type="text/javascript" charset="utf-8"></script>
<link rel="stylesheet" type="text/css" href="http://js.api.here.com/v3/3.0/mapsjs-ui.css" />
</head>
<body>
<div id="map" style="width: 100%; height: 400px; background: grey" />
<script type="text/javascript" charset="utf-8">
//Initialize the Platform object:
var platform = new H.service.Platform({
'app_id': '{YOUR_APP_ID} ',
'app_code': '{YOUR_APP_CODE} '
useHTTPS: true
});
var pixelRatio = window.devicePixelRatio || 1;
var defaultLayers = platform.createDefaultLayers({
tileSize: pixelRatio === 1 ? 256 : 512,
ppi: pixelRatio === 1 ? undefined : 320
});
//Step 2: initialize a map - not specificing a location will give a whole world view.
var map = new H.Map(document.getElementById('map'),
defaultLayers.normal.map, {pixelRatio: pixelRatio});
//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));
// Get the default map types from the Platform object:
map.setCenter({lng: 13.4, lat: 52.51});
map.setZoom(10);
// Instantiate the map:
// Create the default UI:
var ui = H.ui.UI.createDefault(map, defaultLayers, 'de-DE');
var mapSettings = ui.getControl('mapsettings');
var zoom = ui.getControl('zoom');
var scalebar = ui.getControl('scalebar');
var panorama = ui.getControl('panorama');
panorama.setAlignment('top-left');
mapSettings.setAlignment('top-left');
zoom.setAlignment('top-left');
scalebar.setAlignment('top-left');
var bubble = new H.ui.InfoBubble({ lng: 13.4, lat: 52.51 }, {
content: '<b>Hello World!</b>'
});
// Add info bubble to the UI:
ui.addBubble(bubble);
</script>
</body>
</html>
I'm Richard and I'm a developer evangelist for HERE.
Your code breaks in this line:
panorama.setAlignment('top-left');
This line indicates that you want to move the StreetLevel UI element to the top-left of the map. However this element does not exist, as you've forgotten to import the mapsjs-pano.js library. This library is required for StreetLevel functionality. Add the following line to your and your code should work.
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-pano.js"></script>
Also note that you are missing a comma after setting your app_code and that your importing some libraries twice. You may have to fix these issues as well for your code to work. Here is a cleaned up version of your code that does what you want to do.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
<link rel="stylesheet" type="text/css" href="https://js.api.here.com/v3/3.0/mapsjs-ui.css" />
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-core.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-service.js"></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>
<script type="text/javascript" src="https://js.api.here.com/v3/3.0/mapsjs-pano.js"></script>
</head>
<body>
<div id="map" style="width: 100%; height: 400px; background: grey" />
<script type="text/javascript" charset="UTF-8" >
function createInfoBubble(map) {
// Create info bubble
var bubble = new H.ui.InfoBubble({ lng: 13.4, lat: 52.51 }, {
content: '<b>Hello World!</b>'
});
// Add info bubble to the UI:
ui.addBubble(bubble);
}
// Step 1: initialize the platform
var platform = new H.service.Platform({
app_id: '{YOUR_APP_ID}',
app_code: '{YOUR_APP_CODE}',
useHTTPS: true
});
var pixelRatio = window.devicePixelRatio || 1;
var defaultLayers = platform.createDefaultLayers({
tileSize: pixelRatio === 1 ? 256 : 512,
ppi: pixelRatio === 1 ? undefined : 320
});
// Step 2: initialize a map
var map = new H.Map(document.getElementById('map'),
defaultLayers.normal.map, {pixelRatio: pixelRatio});
// Step 3: make the map interactive
var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
// Step 4: create the default UI components
var ui = H.ui.UI.createDefault(map, defaultLayers);
// Move UI elements to the top left of the map
var mapSettings = ui.getControl('mapsettings');
var zoom = ui.getControl('zoom');
var scalebar = ui.getControl('scalebar');
var panorama = ui.getControl('panorama');
panorama.setAlignment('top-right');
mapSettings.setAlignment('top-left');
zoom.setAlignment('top-left');
scalebar.setAlignment('top-left');
// Move map to Berlin
map.setCenter({lat:52.5159, lng:13.3777});
map.setZoom(14);
createInfoBubble(map);
</script>
</body>
</html>

Reload data for OpenLayers.Layer.Text marker automatically

I am currently trying to layer some markers over a OSM map using OpenLayers. The page should refresh in a certain interval and load new data from the DB.
I feed the data from the DB to the OpenLayers.Layer.Text through a local servlet which constructs the input file from the records in the DB.
My current approach is to simpy use <meta http-equiv="refresh" content="3"> which reloads the page and subsequently the script. Problem with this approach is, that the OSM map is reset, i.e. zoom, view port, etc.
I have thus tried to use a refresh strategy from OpenLayers but this does not seem to reload the data from the servlet for the corresponding layer.
<!DOCTYPE html>
<html>
<head>
<title>OSM View/title>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<!--meta http-equiv="refresh" content="3"-->
</head>
<body>
<div id="mapdiv" style="height:750px"></div>
<script src="http://www.openlayers.org/api/OpenLayers.js"></script>
<script>
var lat = 52;
var lon = 10;
var zoom = 18;
map = new OpenLayers.Map("mapdiv", {
controls: [
new OpenLayers.Control.Navigation(),
new OpenLayers.Control.PanZoomBar(),
new OpenLayers.Control.LayerSwitcher()
],
projection: 'EPSG:900913',
displayProjection: 'EPSG:4326',
numZoomLevels: 18,
units: 'm'
});
mapnik = new OpenLayers.Layer.OSM("Karte");
map.addLayer(mapnik);
var marker = new OpenLayers.Layer.Text("marker", {
location: "http://localhost:8080/marker",
projection: map.displayProjection,
strategies: [new OpenLayers.Strategy.Refresh({interval: 3000, force: true})]
});
map.addLayer(marker);
var fromProjection = new OpenLayers.Projection("EPSG:4326"); // Transform from WGS 1984
var toProjection = new OpenLayers.Projection("EPSG:900913"); // to Spherical Mercator Projection
var position = new OpenLayers.LonLat(lon, lat).transform(fromProjection, toProjection);
map.setCenter(position, zoom);
</script>
</body>
</html>
Is there a way to achieve what I am trying to do?
OpenLayers.Layer.Text does not support strategies.
Looking at the code, there isn't any function to reload the data, but you should be able to reload layer data using:
setInterval(function() {
layer.clearFeatures();
layer.loaded = false;
layer.loadText();
}, 3 * 1000);

Empty Android WebView with Google Maps and Position

I got problems with Android WebView and my webpage.
The page is ok in my Chrome Browser, but stays empty in the Android webview (Internet Permission granted, but no additional Permissions granted in the Manifest).
Do you have any hints for me? The other answers don't seem to apply here.
Normally I would use Googles Map View Control in Android, but in that case I really have to use a WebView. And I'm really bad at JavaScript :-(
my Javascript looks like this:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<script src="https://maps.google.com/maps/api/js?v=3.exp">
</script>
<script>
if (navigator.geolocation) {
alert("Geolocation IS supported.");
navigator.geolocation.getCurrentPosition(showCurrentLocation);
} else {
alert("Geolocation API not supported.");
}
function showCurrentLocation(position) {
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
var coords = new google.maps.LatLng(latitude, longitude);
var mapOptions = {
zoom : 15,
center : coords,
mapTypeControl : true,
mapTypeId : google.maps.MapTypeId.ROADMAP
};
//create the map, and place it in the HTML map div
map = new google.maps.Map(document.getElementById("mapPlaceholder"),
mapOptions);
//place the initial marker
var marker = new google.maps.Marker({
position : coords,
map : map,
title : "Current location!"
});
}
</script>
</head>
<style>
mapPlaceholder {
height: 400px;
width: 700px;
background-color: graytext;
}
</style>
<body>
<div>
<div id="mapPlaceholder"></div>
</div>
</body>
</html>
and the Android Code:
WebView wvTask = (WebView) findViewById(R.id.wvTask);
wvTask.getSettings().setJavaScriptEnabled(true);
wvTask.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
wvTask.getSettings().setLoadWithOverviewMode(true);
wvTask.getSettings().setUseWideViewPort(true);
wvTask.getSettings().setBuiltInZoomControls(true);
wvTask.getSettings().setPluginState(WebSettings.PluginState.ON);
wvTask.getSettings().setGeolocationEnabled(true);
wvTask.getSettings().setLoadsImagesAutomatically(true);
wvTask.setWebChromeClient(new WebChromeClient());
wvTask.getSettings().setDomStorageEnabled(true);
wvTask.getSettings().setAppCacheEnabled(true);
wvTask.getSettings().setDatabaseEnabled(true);
wvTask.loadUrl(XXX); //here is my URL, tried both https and http - nothing worked.

PhoneGap Android: Google map api v3 showing blank screen

I am building an webapp using phonegap cordova 2.9.0. The app developed is working fine in the desktop browser but when i try to run app in android device (After getting build using build_tool it shows the first alert generated by my javascript. After that only a blank white screen appears nothing else.
The link to the app source at is link. In this app i am trying to get users current location using
navigator.geolocation
The app aims to show all available bitcoin trade places in google map withing given radius of user location.
App can be downloaded using this link.
Update:
I am able to get the geolocation points and show them in alert, but wehn i try to render them on map with marker, then map is not rendering on android device. (Working on desktop browser)
index.html
<!DOCTYPE html>
<html>
<head>
<title>tittle</title>
<script>
window.location='./main.html';
</script>
<body>
</body>
</html>
main.html
<!DOCTYPE html>
<html>
<head>
<title>CoinMap</title>
<meta charset="utf-8">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script src="js/jquery.js"></script>
<script src="http://maps.google.com/maps/api/js?key=AIzaSyA-zLxKvbiIbO8uR20Z5DemPXYh1F3bm1M&sensor=false"></script>
<script src="js/coinmap.js"></script><!--
<script src="js/coinmap-icons.js"></script>-->
<link href="css/style.css" rel="stylesheet" type="text/css" />
<link rel="icon" type="image/png" href="bitcoin.png" />
<meta name="keywords" content="coinmap,map,bitcoin,openstreetmap" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
</head>
<body>
<!--<body onload="getCoinData()">-->
<div id="map"></div>
<div id="count"></div>
<script>
alert("Getting your location....");
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
if (navigator.geolocation)
{
navigator.geolocation.getCurrentPosition(coinmap, onError, {maximumAge: 300000, timeout:10000, enableHighAccuracy : true});
}
else{
alert("GeoLocation is not available.");}
};
</script>
</body>
</html>
coinmap.js
function coinmap(position) {
alert("Latitude: " + position.coords.latitude + "\n" +
"Longitude:" + position.coords.longitude + "\n");
var lat = position.coords.latitude;
var lng = position.coords.longitude;
loadMap(lat, lng);
}
function loadMap(latitude, longitude){
var my_latLng = new google.maps.LatLng(latitude,longitude);
var mapOptions = {
zoom: 8,
center: my_latLng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById('map'), mapOptions);
var my_marker = new google.maps.Marker({
position: my_latLng,
map: map,
title: 'My Position'
});
var markers = [];
var user_radius = 1000000;
$.getJSON("http://overpass.osm.rambler.ru/cgi/interpreter?data=[out:json];(node[%22payment:bitcoin%22=yes];way[%22payment:bitcoin%22=yes];%3E;);out;", function (data) {
$.each(data.elements, function (key, value) {
var latLng = new google.maps.LatLng(value.lat, value.lon);
var marker = new google.maps.Marker({
'position': latLng
});
markers.push(marker);
});
// Define the circle
var circle = new google.maps.Circle({
map: map,
clickable: false,
// metres
radius: user_radius,
fillColor: '#fff',
fillOpacity: .6,
strokeColor: '#313131',
strokeOpacity: .4,
strokeWeight: .8
});
// Attach circle to marker
circle.bindTo('center', my_marker, 'position');
// Get the bounds
var bounds = circle.getBounds();
for (var i = 0; i < markers.length; i++) {
if (bounds.contains(markers[i].getPosition())) {
markers[i].setMap(map);
} else {
markers[i].setMap(null);
}
}
});
}
function onError(error) {
alert('code: ' + error.code + '\n' +
'message: ' + error.message + '\n');
}
This above code is working well in chrome and firefox and mobile browser also, but not working as a wepapp after build using phonegap. Any help will be appreciated.
Any geolocation example with rendering location on map can also be helpful.
I ran into this exact same problem and found the issue to be with the options passed in. If you look at the current example on phonegap.com for getCurrent location: http://docs.phonegap.com/en/edge/cordova_geolocation_geolocation.md.html#Geolocation
You'll notice no options are passed in, it's simply: navigator.geolocation.getCurrentPosition(onSuccess, onError);
I deleted my options and the map popped right up. I have not looked deeper into it since, so I cannot tell you the cause, but please try deleting your options and see if it works.

Embedding a Google map

I have embedded a Google Map in my website. I want to change its location according to user input. How can I do this?
I tried to copy the link of the location and assign it to the iframe src:
$("iframe").attr("src", "https://maps.google.co.in/maps?q=USA&hl=en&ll=37.09024,-95.712891&spn=131.016476,346.289063&sll=23.259933,77.412615&sspn=0.178842,0.338173&oq=usa&doflg=ptm&hnear=United+States&t=m&z=2");
but the iframe is not loading the map.
Try to use the GoogleMaps JavaScript API. The offer way more control (geocode, searching, custom marker, etc...) over the map then just embedding a iframe.
Take a look at this :)
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<link href="http://code.google.com/apis/maps/documentation/javascript/examples/default.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
// Initiate map
function initialize(data) {
// Make position for center map
var myLatLng = new google.maps.LatLng(data.lng, data.lat);
// Map options
var myOptions = {
zoom: 10,
center: myLatLng,
mapTypeId: google.maps.MapTypeId.HYBRID
};
// Initiate map
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
// Info window element
infowindow = new google.maps.InfoWindow();
// Set pin
setPin(data);
}
// Show position
function setPin(data) {
var pinLatLng = new google.maps.LatLng(data.lng, data.lat);
var pinMarker = new google.maps.Marker({
position: pinLatLng,
map: map,
data: data
});
// Listen for click event
google.maps.event.addListener(pinMarker, 'click', function() {
map.setCenter(new google.maps.LatLng(pinMarker.position.lat(), pinMarker.position.lng()));
map.setZoom(18);
onItemClick(event, pinMarker);
});
}
// Info window trigger function
function onItemClick(event, pin) {
// Create content
var contentString = pin.data.text + "<br /><br /><hr />Coordinate: " + pin.data.lng +"," + pin.data.lat;
// Replace our Info Window's content and position
infowindow.setContent(contentString);
infowindow.setPosition(pin.position);
infowindow.open(map)
}
</script>
</head>
<body onload="initialize({lat:-3.19332,lng:55.952366,text:'<h2>Edinburgh</h2><i>Nice city!</i>'})">
<div id="map_canvas">
</div>
</body>
</html>

Categories

Resources