I'm trying to do some simple drawing on OpenStreetMap data using OpenLayers (version 6.5.0). The map loads fine. I try to do the drawing when the button in the top right is clicked.
I convert this array of GPS coordinates into a Polygon, into a Feature, into an ol.source.Vector, into an ol.layer.Vector. I log every object constructed along the way on the console. This appears to go fine.
I finally want to add the (Vector) layer to the existing map using the .addLayer() function.
At this point, things go wrong inside the OpenLayer 6.5.0 JavaScript code. Deep inside the ol.js code, it throws a TypeError: t.addEventListener is not a function.
Browser screenshot
I've looked at multiple examples:
https://openlayers.org/en/latest/examples/polygon-styles.html
https://openlayers.org/en/latest/examples/geojson.html
So far, I have no clue whether this a bug in OpenLayer 6.5.0 or I'm missing something during conversion of my GPS coordinates array into an ol.layer.vector object. Any hints on this?
Entire html/javascript code below:
<meta charset="UTF-8">
<html>
<head>
<title>OSM test</title>
<link rel="stylesheet" href="ol.css">
<script src="ol.js"></script>
<script type="text/javascript">
function loadMap(domDivId, szLat, szLon, zoom) {
var vView = new ol.View({
center: ol.proj.fromLonLat([szLon, szLat]),
zoom: zoom
});
var lTile = new ol.layer.Tile({
source: new ol.source.OSM()
})
var map = new ol.Map({
target: domDivId,
layers: [lTile],
view: vView
});
return map;
}
function drawBermuda(map) {
// Bermuda triangle (approximate) GPS coordinates in [lat,lon] format
var arPath = [
[18.472282,-66.123934], // Bermuda
[32.297504,-64.778447], // Puerto Rico
[25.732447,-80.133221], // Miami
[18.472282,-66.123934] // Bermuda
];
console.log(arPath);
var pPath = {
'type': 'Polygon',
'coordinates': arPath
};
console.log(pPath);
var fPath = {
'type': 'Feature',
'geometry': pPath
};
console.log(fPath);
var svPath = new ol.source.Vector({
features: new ol.format.GeoJSON().readFeatures(fPath)
});
console.log(svPath);
var lvPath = new ol.layer.Vector({
source: svPath,
});
console.log(lvPath);
map.addLayer([lvPath]);
}
</script>
</head>
<body>
<div id="div_map" style="width:100%; height:100%; position:absolute; left:0px; top:0px; margin:0px; padding;0px; z-index:-10"></div>
<script>
map = loadMap('div_map', 25.0, -71.0, 5);
</script>
<div style="float:right">
<button onclick="drawBermuda(map);" style="height:100;width:100px;">click me please :-)</button>
</div>
</body>
</html>
P.S. I am aware that I still may have to swap latitude and longitude and convert the coordinates in some other way for OpenLayer to interpret them correctly. But that's not the main point here. I guess...
As well as missing and misplaced [ ] geojson coordinates must be specified in lon, lat order and features must be read into the view projection
<meta charset="UTF-8">
<html>
<head>
<title>OSM test</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.5.0/css/ol.css" type="text/css">
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.5.0/build/ol.js"></script>
<script type="text/javascript">
function loadMap(domDivId, szLat, szLon, zoom) {
var vView = new ol.View({
center: ol.proj.fromLonLat([szLon, szLat]),
zoom: zoom
});
var lTile = new ol.layer.Tile({
source: new ol.source.OSM()
})
var map = new ol.Map({
target: domDivId,
layers: [lTile],
view: vView
});
return map;
}
function drawBermuda(map) {
// Bermuda triangle (approximate) GPS coordinates in [lon,lat] format
var arPath = [[
[-66.123934, 18.472282], // Bermuda
[-64.778447, 32.297504], // Puerto Rico
[-80.133221, 25.732447], // Miami
[-66.123934, 18.472282] // Bermuda
]];
var pPath = {
'type': 'Polygon',
'coordinates': arPath
};
var fPath = {
'type': 'Feature',
'geometry': pPath
};
var svPath = new ol.source.Vector({
features: new ol.format.GeoJSON().readFeatures(fPath, {featureProjection: map.getView().getProjection()})
});
var lvPath = new ol.layer.Vector({
source: svPath,
});
map.addLayer(lvPath);
}
</script>
</head>
<body>
<div id="div_map" style="width:100%; height:100%; position:absolute; left:0px; top:0px; margin:0px; padding;0px; z-index:-10"></div>
<script>
map = loadMap('div_map', 25.0, -71.0, 5);
</script>
<div style="float:right">
<button onclick="drawBermuda(map);" style="height:100;width:100px;">click me please :-)</button>
</div>
</body>
</html>
Related
I´m trying to apply the Leaflet.MarkerCluster.LayerSupport. But I don´t know how to use it :( I´ve already read the documentation about but and I tried many times but it doesen´t work.
This is my code
<!DOCTYPE html>
<html>
<head>
<title>Península</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.css" />
</head>
<body>
<div id="map" style="width: 600px; height: 400px"></div>
<script src="http://cdn.leafletjs.com/leaflet/v0.7.7/leaflet.js"></script>
<script src='https://api.mapbox.com/mapbox.js/plugins/leaflet-markercluster/v0.4.0/leaflet.markercluster.js'></script>
<script src="leaflet.markercluster.layersupport-src.js"></script>
<script>
var NemachIcons =L.Icon.extend({
options:{
shadowUrl:'',
iconSize: [50,55],
iconAnchor: [45,45],
popupAnchor:[-3,-76]
}
});
var tiloIcon = new NemachIcons({iconUrl:'http://www.iconshock.com/img_jpg/SIGMA/general/jpg/256/pyramid_icon.jpg'}),
puebloIcon = new NemachIcons({iconUrl:'http://icons.iconseeker.com/png/fullsize/gant/pointless-bw-circle-i-use-it-iex.png'}),
gasIcon =new NemachIcons({iconUrl:'https://cdn2.iconfinder.com/data/icons/function_icon_set/circle_green.png'});
L.icon =function (options) {
return new L.Icon(options);
};
var sitios = new L. LayerGroup();
L.marker([20.683, -88.568], {icon: tiloIcon}).bindPopup('1').addTo(sitios),
L.marker([21.204547, -89.269466], {icon: tiloIcon}).bindPopup('2').addTo(sitios),
L.marker([20.332362, -89.647899], {icon: tiloIcon}).bindPopup('3').addTo(sitios),
L.marker([20.486417, -88.660218], {icon: tiloIcon}).bindPopup('4').addTo(sitios),
L.marker([21.151196, -87.958143], {icon: tiloIcon}).bindPopup('5').addTo(sitios);
var pueblo = new L.LayerGroup();
L.marker([20.9330, -89.0178], {icon: puebloIcon}).bindPopup('6').addTo(pueblo),
L.marker([20.6909, -88.2015], {icon: puebloIcon}).bindPopup('7').addTo(pueblo);
var gas = new L.LayerGroup();
L.marker([20.973907, -89.578931], {icon: gasIcon}).bindPopup('8').addTo(gas);
var mbAttr = ' ' +
'' +
'',
mbUrl = 'https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpandmbXliNDBjZWd2M2x6bDk3c2ZtOTkifQ._QA7i5Mpkd_m30IGElHziw';
var grayscale = L.tileLayer(mbUrl, {id: 'mapbox.light', attribution: mbAttr}),
streets = L.tileLayer(mbUrl, {id: 'mapbox.streets', attribution: mbAttr});
var map = L.map('map', {
center: [20.794527, -88.760612],
zoom: 8,
layers: [grayscale, sitios]
});
var baseLayers = {
//"Grayscale": grayscale,
//"Streets": streets
};
var overlays = {
"Pirámide": sitios,
"Poblado": pueblo,
"Servicio": gas
};
L.control.layers(baseLayers, overlays).addTo(map);
</script>
</body>
</html>
I´ll appreciate all your answers
Like for Leaflet.markercluster, you have to create a Marker Cluster Group where your sub-groups will go into.
In the case of Layer Support, you create a Marker Cluster Group with Layer Support instead:
var mcg = L.markerClusterGroup.layerSupport().addTo(map);
Then you "check in" the sub-groups, so that they know they have to go into that clustering group rather than directly to the map, when they are selected through the Layers Control:
mcg.checkIn([
sitios,
pueblo,
gas
]);
Demo: http://plnkr.co/edit/CT3E63AKWze34FqUoiHn?p=preview
Note: you should download the JavaScript file leaflet.markercluster.layersupport-src.js, if not already done, and place it next to your HTML page, so that it can refer to it locally.
Note 2: if your usage requires only compatibility of clustering with L.Control.Layers, you might be interested in this more simple plugin: Leaflet.FeatureGroup.SubGroup.
Disclaimer: I am the author of these plugins.
I have a web page and I was wondering if I am calling correctly javascript3.js. The file is inside the same folder as the html. When I put the javascript code inside the html, it works fine.
(The ol3-layerswitcher.js is being called correctly so I don't know why the other one is not being called.)
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Map</title>
<link rel="stylesheet" href="http://openlayers.org/en/v3.12.1/css/ol.css">
<link rel="stylesheet" href="ol3-layerswitcher.css">
<script src="http://openlayers.org/en/v3.12.1/build/ol.js"></script>
<script src="ol3-layerswitcher.js"></script>
<script src="javascript3.js"></script>
</head>
<body>
<div id="map" style="width:100%;"></div>
<div id="info"></div>
</body>
</html>
javascript3.js:
var testSource = new ol.source.TileWMS({
url: 'http://localhost:8080/geoserver/wms',
params: {'LAYERS': 'Marine:Great_Britain', 'TILED': true},
serverType: 'geoserver'
});
var layers = [
new ol.layer.Tile({
source: new ol.source.MapQuest({layer: 'osm'})
}),
new ol.layer.Group({
title: 'Layers',
layers: [
//Implementing layers
new ol.layer.Tile({
title: 'Great Britain',
source: testSource
}),
]
})
];
var map = new ol.Map({
layers: layers,
target: 'map',
view: new ol.View({
center: [51480.6, 7216744.2], //UK
zoom: 5
})
});
//Function to get features from layer
map.on('singleclick', function(evt) {
document.getElementById('info').innerHTML = '';
viewResolution = map.getView().getResolution();
var url = testSource.getGetFeatureInfoUrl(
evt.coordinate, viewResolution, 'EPSG:3857',
{'INFO_FORMAT': 'text/html'});
if (url) {
document.getElementById('info').innerHTML =
'<iframe seamless src="' + url + '"></iframe>';
}
});
//Layer switcher to turn layers on and off
var layerSwitcher = new ol.control.LayerSwitcher({
tipLabel: 'Legend'
});
map.addControl(layerSwitcher);
If you need to execute DOM manipulation without wrapping your code into document ready handler (such as $(document).ready();), the correct place is at the end of body (or at least after creating the DOM elements to be manipulated):
<!DOCTYPE html>
<html>
<head>
<title>Map</title>
<link rel="stylesheet" href="http://openlayers.org/en/v3.12.1/css/ol.css">
<link rel="stylesheet" href="ol3-layerswitcher.css">
<script src="http://openlayers.org/en/v3.12.1/build/ol.js"></script>
<script src="ol3-layerswitcher.js"></script>
</head>
<body>
<div id="map" style="width:100%;"></div>
<div id="info"></div>
<script src="javascript3.js"></script>
</body>
</html>
I have problem with the execution of the javascript inside a jsp page.
I have the following page which works perfectly if I call it from my filesystem, that is, I write in the address bar C:\...\heatmap2.jsp.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<title>Energy Heatmap </title>
<style>
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map-canvas { height: 80% }
h1 { position:absolute; }
</style>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?libraries=visualization&sensor=true?key=AIzaSyCzoFE1ddY9Ofv0jjOvA3yYdgzV4JvCNl4"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type='text/javascript'>
/*Array in cui saranno inseriti i punti da visualizzare nella mappa
*/
var heatMapData = new Array();
function loadHeatMapData(callback)
{
$.ajax
({
type: "GET",
url: "http://localhost:8080/EnergyManagement-portlet/api/secure/jsonws/sample/get-samples-time-by-name?energyName=EnAssGS",
dataType: "jsonp",
crossDomain: true,
cache: false,
success: function(jsonData)
{
for (var i = 0; i < jsonData.length; i++)
{
var decodedData = JSON.parse(jsonData[i]);
var lng = decodedData["_longitude"];
var lat = decodedData["_latitude"];
var energyIntensity = decodedData["_value"];
heatMapData.push({location: new google.maps.LatLng(lat, lng), weight: energyIntensity});
}
return callback(heatMapData);
}
})
}
function drawHeatMap()
{
// map center
var myLatlng = new google.maps.LatLng(40.8333333, 14.25);
// map options,
var myOptions = {
zoom: 5,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.TERRAIN
};
// standard map
map = new google.maps.Map(document.getElementById("map-canvas"), myOptions);
var heatMap = new google.maps.visualization.HeatmapLayer({
data: heatMapData,
dissipating: false
});
heatMap.setMap(map);
/*
Questi punti dovrebbero prevenire da un file.
*/
var vehiclePath = [
new google.maps.LatLng(40.85235, 14.26813),
new google.maps.LatLng(40.85236, 14.26822),
new google.maps.LatLng(40.85236, 14.26822),
new google.maps.LatLng(40.85236, 14.26816),
new google.maps.LatLng(40.85258, 14.26811),
new google.maps.LatLng(40.85364, 14.26793),
new google.maps.LatLng(40.85414, 14.26778),
new google.maps.LatLng(40.8554, 14.2676),
new google.maps.LatLng(40.8579, 14.27286),
new google.maps.LatLng(40.85821, 14.27291),
new google.maps.LatLng(40.8584, 14.27302),
new google.maps.LatLng(40.85859, 14.27325),
new google.maps.LatLng(40.8587, 14.27421),
new google.maps.LatLng(40.85865, 14.27433),
new google.maps.LatLng(40.85866, 14.27446),
new google.maps.LatLng(40.86656, 14.291),
new google.maps.LatLng(40.86653, 14.29102)
];
var path = new google.maps.Polyline({
path: vehiclePath,
geodesic: true,
strokeColor: '#FF0000',
strokeOpacity: 1.0,
strokeWeight: 2
});
path.setMap(map);
}
/*Callback*/
loadHeatMapData(drawHeatMap)
</script>
</head>
<body>
<div id="map-canvas"></div>
<p id="demo"></p>
</body>
</html>
Unfortunately, when I try to call it inside my Liferay portal, I can't see any javascript running.
The following code creates a heatmap (with the Google API), the points are obtained with an asynchronous call to the webserver
via SOAP (it's a method available from an entity of my project).
I also tried to add the tag
<header-portlet-javascript>
"https://maps.googleapis.com/maps/api/js?libraries=visualization sensor=true?key=AIzaSyCzoFE1ddY9Ofv0jjOvA3yYdgzV4JvCNl4"
</header-portlet-javascript>
with no sucess.
Any help is appreciated.
Without being able to test your code currently, I see two issues with it:
Your JSP contains <html>, <head> and <body> elements etc. These are not allowed in portlets and won't work the same way as in a standalone page
Further, your contains superfluous quotes.
<header-portlet-javascript>
"https://maps.googleapis.com/and/so/on"
</header-portlet-javascript>
I'd expect this to literally be added to the page, resulting in double quotes
<script type="text/javascript" src=""https://maps.googleapis.com/and/so/on""></script>
Obviously, this doesn't work. Please check what ends up on the generated page when you add your portlet to it. Also, remove the extra quotes and try again.
Deae Olaf,
I applied your advice to my code.
With the support of the internet explorer debbuger, I found out that the code inside the drawHeatmpaData is like being commented (please, look at the picture)
.
In order to prevent from you code being commented, I found that we cannot use // to comment,
because all the text even the code is treated as comment.
I replace all // with /**/ but it still does not work.
I am trying to get the weather information for a certian cities(cities are coming dynamically) and i came across this map api which is very easy to integrate. but once i tried it, it is showing only moscow even if i gave the lat and lon of another city, say, munich.
this is the code:
<html>
<head>
<script src="http://openlayers.org/api/OpenLayers.js"></script>
<script src="http://openweathermap.org/js/OWM.OpenLayers.1.3.4.js" ></script>
</head>
<body onload="init()">
<div id="basicMap"></div>
</body>
<script type="text/javascript">
function init() {
//Center of map
var lat = 48.24806; // <--- some dynamic location
var lon = 11.90166; //<--- some dynamic location
var lonlat = new OpenLayers.LonLat(lon, lat);
var map = new OpenLayers.Map("basicMap");
// Create overlays
// OSM
var mapnik = new OpenLayers.Layer.OSM();
// Stations
var stations = new OpenLayers.Layer.Vector.OWMStations("Stations");
// Current weather
var city = new OpenLayers.Layer.Vector.OWMWeather("Weather");
//Addind maps
map.addLayers([mapnik, stations, city]);
map.setCenter( lonlat, 10 );
}
</script>
</html>
i just want to save some loading energy for my server and do this weather issue in frontend with js. if this would work, it would be wonderful, please help if you can. why am i stuck to moscow here even if give different lat and lons. this is the link for api:
http://openweathermap.org/tutorial/openlayers
Apparently you need to set the Projection for it to work correctly.
Here is an example of the code centering at London:
<html>
<head>
<script src="http://openweathermap.org/js/OWM.OpenLayers.1.3.4.js" ></script>
</head>
<body onload="init()">
<div id="basicMap"></div>
</body>
<script type="text/javascript">
function init() {
//Center of map
var lat = 51.5112139; // <--- some dynamic location
var lon = -0.1198244; //<--- some dynamic location
var map = new OpenLayers.Map("basicMap");
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);
// Create overlays
// OSM
var mapnik = new OpenLayers.Layer.OSM();
// Stations
var stations = new OpenLayers.Layer.Vector.OWMStations("Stations");
// Current weather
var city = new OpenLayers.Layer.Vector.OWMWeather("Weather");
//Addind maps
map.addLayers([mapnik, stations, city]);
map.setCenter( position, 5 );
}
</script>
</html>
To get the Longitude and Latitude of your place, you can use this URL:
http://www.mapcoordinates.net/en
Hope this helps
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="style.css" type="text/css">
<script src="http://openlayers.org/api/2.10/OpenLayers.js" type="text/javascript">
var map, layer;
function init(){
map = new OpenLayers.Map( 'map', {controls: [
new OpenLayers.Control.Navigation({documentDrag: true}),
new OpenLayers.Control.PanZoom(),
new OpenLayers.Control.ArgParser(),
new OpenLayers.Control.Attribution()
]} );
layer = new OpenLayers.Layer.WMS( "OpenLayers WMS",
"http://vmap0.tiles.osgeo.org/wms/vmap0",
{layers: 'basic'} );
map.addLayer(layer);
map.zoomToMaxExtent();
}
</script>
</head>
<body onload="init()">
<h1 id="title">OpenLayers Document Drag Example</h1>
<div id="tags">
drag
</div>
<div id="shortdesc">Keep on dragging even when the mouse cursor moves outside of the map</div>
<div id="map" class="smallmap"></div>
<div id="docs">
<p>This example shows how to make a map draggable outside of the map itself.</p>
</div>
</body>
</html>
That is my html code with the javascript . My firebug throws up the error init() not defined . What can be the error ?
Your <script> element loads its content from an external resource (http://openlayers.org/api/2.10/OpenLayers.js) since you specified that URL in its src attribute.
Therefore, the browser will ignore the actual content of the element, so init() won't be defined.
Try using two <script> elements instead:
<script src="http://openlayers.org/api/2.10/OpenLayers.js" type="text/javascript">
</script>
<script type="text/javascript">
var map, layer;
function init(){
map = new OpenLayers.Map( 'map', {controls: [
new OpenLayers.Control.Navigation({documentDrag: true}),
new OpenLayers.Control.PanZoom(),
new OpenLayers.Control.ArgParser(),
new OpenLayers.Control.Attribution()
]} );
layer = new OpenLayers.Layer.WMS( "OpenLayers WMS",
"http://vmap0.tiles.osgeo.org/wms/vmap0",
{layers: 'basic'} );
map.addLayer(layer);
map.zoomToMaxExtent();
}
</script>
This might help:
http://openlayers.org/dev/examples/lite.html
It is the basic and simplest example of Openlayers.