Reload data for OpenLayers.Layer.Text marker automatically - javascript

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);

Related

Building OpenStreetMap into a WordPress Custom Plugin

I am building a WordPress plugin that involves the use of maps and user created custom markers. I want to separate the map from the marker so that a user can create custom markers cross map platform and keep the marker data on there WordPress page.
I set up a development server on a raspberry pi 3 B, with a 2 Terabyte hard drive that it boots from. I set up an OpenStreetMap tile server of North America to practice on and I got it up and through and html file in my /var/www/html that runs through a LAMP server that also includes my WordPress development web server.
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
<title>Public Transport Lines - ÖV-Linien - openptmap.org</title>
<link rel="shortcut icon" href="favicon_pt.png">
<link rel="stylesheet" href="style.css" type="text/css">
<style> /* avoid empty tiles */ .olImageLoadError {display: none;}
</style>
<script src="OpenLayers.js" type="text/javascript"></script>
<script src="OpenStreetMap.js" type="text/javascript"></script>
<script type="text/javascript">
var map;
function init() {
// The overlay layer for our marker, with a simple diamond as symbol
var overlay = new OpenLayers.Layer.Vector('Overlay', {
styleMap: new OpenLayers.StyleMap({
externalGraphic: '../img/marker.png',
graphicWidth: 20, graphicHeight: 24, graphicYOffset: -24,
title: '${tooltip}'
})
});
// The location of our marker and popup. We usually think in geographic
// coordinates ('EPSG:4326'), but the map is projected ('EPSG:3857').
var myLocation = new OpenLayers.Geometry.Point(10.2, 48.9)
.transform('EPSG:4326', 'EPSG:3857');
// We add the marker with a tooltip text to the overlay
overlay.addFeatures([
new OpenLayers.Feature.Vector(myLocation, {tooltip: 'OpenLayers'})
]);
// A popup with some information about our location
var popup = new OpenLayers.Popup.FramedCloud("Popup",
myLocation.getBounds().getCenterLonLat(), null,
'<a target="_blank" href="http://openlayers.org/">We</a> ' +
'could be here.<br>Or elsewhere.', null,
true // <-- true if we want a close (X) button, false otherwise
);
// Finally we create the map
map = new OpenLayers.Map({
div: "map", projection: "EPSG:3857",
layers: [new OpenLayers.Layer.OSM(), overlay],
center: myLocation.getBounds().getCenterLonLat(), zoom: 15
});
// and add the popup to it.
map.addPopup(popup);
}
</script>
</head>
<body onload="init();">
<div style="width:100%; height:100%;" id="map"></div><br></body>
</html>
This is an example of the example marker that I created which I can use a short code to link to in my plugin, but I can't get scripts to run in the plugin itself with results on the map.
For example when I run this script in my plugin attached to just a plain map.html iframe it doesn't do anything.

Stop to add points in a polygon with openlayers 5.3.0

In my web page, users can draw a polygon and then modify it. However, I would like to only allow users to drag and drop the drawn corners, not add new points into polygon when a polygon is modified.
In the example below, I created a polygon with four corners and would like to keep four corners during modifying (only drag the corners).
I think we should use condition in the modify function, but not sure how to find out the difference between clicking the corner or edge of a polygon.
<!DOCTYPE html>
<html>
<head>
<title>Draw Features</title>
<link rel="stylesheet" href="https://openlayers.org/en/v5.3.0/css/ol.css" type="text/css">
<script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
</head>
<body>
<div id="map" class="map"></div>
<script>
var raster = new ol.layer.Tile({
source: new ol.source.OSM()
});
var source = new ol.source.Vector({wrapX: false});
var offset = 1000000;
var ply = new ol.geom.Polygon([[
[-11000000 - offset, 4600000 - offset],
[-11000000 + offset, 4600000 - offset],
[-11000000 + offset, 4600000 + offset],
[-11000000 - offset, 4600000 + offset]]]);
var feature = new ol.Feature(ply);
source.addFeatures([feature]);
var vector = new ol.layer.Vector({
source: source
});
var map = new ol.Map({
layers: [raster, vector],
target: 'map',
view: new ol.View({
center: [-11000000, 4600000],
zoom: 4
})
});
var modify = new ol.interaction.Modify({source: source})
map.addInteraction(modify);
</script>
</body>
</html>
var modify = new ol.interaction.Modify({
source: source,
insertVertexCondition: ol.events.condition.never
});

How to easily create a heatmap layer from a pre-existing vector layer of points in OpenLayers 3?

Like the title said I have a vector of points on a OpenLayers map that I need to turn into a heatmap. I already have this code below (which works just fine for me) but I need to add thousands of more points(in a different data file) and be able to visualize it with a density/heatmap. Its current state is a simple open street map with one layer of locations plotted on a world map! I would post an image but reputation rules...
<!DOCTYPE HTML>
<html>
<head>
<title>AIS Map Template</title>
<script src="http://www.openlayers.org/api/OpenLayers.js"></script>
<script>
function init() {
map = new OpenLayers.Map("mapdiv");
var mapnik = new OpenLayers.Layer.OSM();
map.addLayer(mapnik);
// ADD POINTS TO A LAYER
var pois = new OpenLayers.Layer.Vector("Ships",
{
projection: new OpenLayers.Projection("EPSG:4326"),
strategies: [new OpenLayers.Strategy.Fixed()],
protocol: new OpenLayers.Protocol.HTTP(
{
url: "./AISdecoded.txt",
format: new OpenLayers.Format.Text(
{
extractStyles: true,
extractAttributes: true
})
})
});
// ADD POINTS LAYER TO MAP
map.addLayer(pois);
var layer_switcher= new OpenLayers.Control.LayerSwitcher({});
map.addControl(layer_switcher);
var lonlat = new OpenLayers.LonLat(0,0).transform(
new OpenLayers.Projection("EPSG:4326"), // transform from WGS 1984
new OpenLayers.Projection("EPSG:900913") // to Spherical Mercator
);
var zoom = 1;
map.setCenter(lonlat, zoom);
}
</script>
<style>
#mapdiv { width:900px; height:600px; }
div.olControlAttribution { bottom:3px; }
</style>
</head>
<body onload="init();">
<p>AIS Map Data</p>
<div id="mapdiv"></div>
</body>
</html>
The testing data looks like this:
lat lon title description icon iconSize iconOffset
49.4756 0.13138 227006760 Navigation Status: 0 ship_sea_ocean.png 16,16 -8,-8
51.2377 4.41944 205448890 Navigation Status: 0 ship_sea_ocean.png 16,16 -8,-8
I have tried various methods to try and get a heatmap produced but unfortunaetly I'm a little lacking on the Javascript/HTML side of things. I have looked at the examples online including the earthquake example provided by OpenLayers but 99% of them deal with KML files and since I need this application to run offline on a localhost server I cannot do it that way.
I have attempted this without success, among other flailing:
var heatmapLayer = new ol.layer.Heatmap({
source: new OpenLayers.Layer.Vector("Ships",
{
projection: new OpenLayers.Projection("EPSG:4326"),
strategies: [new OpenLayers.Strategy.Fixed()],
protocol: new OpenLayers.Protocol.HTTP(
{
url: "./AISdecoded.txt",
format: new OpenLayers.Format.Text(
{
extractStyles: true,
extractAttributes: true
})
})
}),
opacity: 0.9
});
// Create a tile layer from OSM
var osmLayer = new ol.layer.Tile({
source: new ol.source.OSM()
});
// Create the map with the previous layers
var map = new ol.Map({
target: 'map', // The DOM element that will contains the map
renderer: 'canvas', // Force the renderer to be used
layers: [osmLayer, heatmapLayer],
// Create a view centered on the specified location and zoom level
view: new ol.View({
center: ol.proj.transform([2.1833, 41.3833], 'EPSG:4326', 'EPSG:3857'),
zoom: 4
})
});
I have a feeling this is much easier than I think it is but I have been trying to do this for about a week now and my patience is nearing its end. If you know how to do this specifically that's awesome! But if you don't, can you push me in the right direction? Any help is much appreciated, thanks!
EDIT
OK so I edited the code a bit to be fully OL3 and use a geoJSON approach. It now looks like this:
<!DOCTYPE HTML>
<html>
<head>
<title>AIS Map Template</title>
<script src="http://openlayers.org/en/v3.5.0/build/ol.js" type="text/javascript"></script>
<link rel='stylesheet' href='http://ol3js.org/en/master/css/ol.css'>
<script>
function init() {
var vector = new ol.layer.Heatmap({
source: new ol.source.GeoJSON({
url: './AISdecoded.geojson',
projection: 'EPSG:3857'
}),
opacity: .9
});
var osmLayer = new ol.layer.Tile({
source: new ol.source.OSM()
});
// Create the map with the previous layers
var map = new ol.Map({
target: 'map', // The DOM element that will contain the map
renderer: 'canvas', // Force the renderer to be used
layers: [osmLayer,vector],
// Create a view centered on the specified location and zoom level
view: new ol.View({
center: ol.proj.transform([2.1833, 41.3833], 'EPSG:4326', 'EPSG:3857'),
zoom: 4
})
});
}
</script>
<style>
#map { width:900px; height:600px; }
div.olControlAttribution { bottom:3px; }
</style>
</head>
<body onload="init();">
<p>AIS Map Data</p>
<div id="map"></div>
</body>
</html>
But it's still not working, only a map, no layer. This is the way I found how to do via examples like this one. Firebug is saying "TypeError: ol.source.GeoJSON is not a constructor" but I don't know how to do this any other way. pls halp, thanks!
Change this:
var vector = new ol.layer.Heatmap({
source: new ol.source.GeoJSON({
url: './AISdecoded.geojson',
projection: 'EPSG:3857'
}),
to:
var vector = new ol.layer.Heatmap({
source: new ol.source.Vector({
url: './AISdecoded.geojson',
projection: 'EPSG:3857',
format: new ol.format.GeoJSON()
}),

Bing map to display a specific country instead of the whole world?

I'm trying to display a specific country (UK to be exact) in the Bing map instead of the whole world but I have no idea how to!
in my search, i found a blog question and the answer was that it is no possible but I don't think that is true because i have seen it done on many other sites etc..
so I would appreciate it if someone could advise on this issue.
my current code is this:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0"></script>
<script type="text/javascript">
var map = null, infobox, dataLayer;
function GetMap() {
// Initialize the map
map = new Microsoft.Maps.Map(document.getElementById("myMap"),
{ credentials: "XXXXXXXXXXXXXXXXXXXXXXXXXX"
});
dataLayer = new Microsoft.Maps.EntityCollection();
map.entities.push(dataLayer);
var infoboxLayer = new Microsoft.Maps.EntityCollection();
map.entities.push(infoboxLayer);
infobox = new Microsoft.Maps.Infobox(new Microsoft.Maps.Location(0, 0), { visible: false, offset: new Microsoft.Maps.Point(0, 20) });
infoboxLayer.push(infobox);
AddData();
}
function AddData() {
var pin1 = new Microsoft.Maps.Pushpin(new Microsoft.Maps.Location(51.555076763136704, 0.691519856452919));
pin1.Title = "This is Pin 1";
pin1.Description = "Pin 1 description";
Microsoft.Maps.Events.addHandler(pin1, 'click', displayInfobox);
dataLayer.push(pin1);
}
function displayInfobox(e) {
if (e.targetType == 'pushpin') {
infobox.setLocation(e.target.getLocation());
infobox.setOptions({ visible: true, title: e.target.Title, description: e.target.Description });
}
}
</script>
</head>
<body onload="GetMap();">
<div id='myMap' style="position:relative;width:600px;height:400px;"></div>
</body>
</html>
You can't explicitly tell it to zoom to the UK.
But you can create a rectangle (bounding box) and initialize the map using that rectangle as its bounds.
// create a rectangle around the UK (northwest / southeast corners) manually selected
var ukBox = Microsoft.Maps.LocationRect.fromCorners(new Microsoft.Maps.Location(58.909597, -11.449733), new Microsoft.Maps.Location(50.309499, 2.041477));
map = new Microsoft.Maps.Map(document.getElementById("myMap"), {
credentials: "XXXXXXXXXXXXXXXXXXXXXXXXXX",
bounds: ukBox // use the rectangle as the map bounds (for the initial render)
});
Demo at http://jsfiddle.net/gaby/nm1dx07L/
Keep in mind that it will select the closest zoom level that will fit the rectangle. So it depends on the container dimensions.

OpenLayers: Null or undefined error in AddPopup

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>

Categories

Resources