Web Map with OpelLayers, polar projection - javascript

I am quite new into the we map topic and quite frustrated. After reading lots of examples with different libraries etc I managed to get even more confused. So I will start with a trivial example. I provide here the trivial code to plot a web map using openlayers. My aim is to have a polar projection of the map.
html file:
<html>
<head>
<title>Accessible Map</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<link rel="stylesheet" href="https://openlayers.org/en/v4.2.0/css/ol.css" type="text/css">
<link rel="stylesheet" href="style.css">
<script src="https://openlayers.org/en/v4.2.0/build/ol.js"></script>
<script src="map.js"></script>
</head>
<body>
<div id="map" class="map" ></div>
<script>init();</script>
</body>
</html>
javascript:
function init(){
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
target: 'map',
controls: ol.control.defaults({
attributionOptions: /** #type {olx.control.AttributionOptions} */ ({
collapsible: false
})
}),
view: new ol.View({
center: [0, 0],
zoom: 2
})
});
}
This code while produce a map with a default Web Mercator projection (EPSG:3857)
According to https://openlayers.org/en/latest/doc/faq.html
in order to change the projection we need to register our desired one. So in my function I added:
var epsg3413 = new ol.proj.Projection({ //NSIDC Sea Ice Polar Stereographic North
code: "EPSG:3413",
extent: [-4194304, 4194304, 4194304, -4194304],
units: "m"
});
var epsg4326 = ol.proj.get("EPSG:4326");
Then with the view method we can change the map projection so i added:
center: ol.proj.transform([85, 85], epsg4326, epsg3413),
projection: epsg3413
With the additions regarding the projection change the map is not working at all. Even a
console.log(ol.proj.transform([85, 85], epsg4326, epsg3413))
is returning the same point (85,85) which means the projection transformation is not even working. Is there an obvious mistake I am doing here? Please correct me also to this basic question: the ol.source.OSM() gets data from a tiled WMS server. By default the tiles are in web mercator projection. Can I plot them at all in polar stereographic or I should find a WMS server which be default provides tiles in polar projections?

Your projection definition is not correct. I can recommend to use proj4j:
// projection definition (http://www.spatialreference.org/ref/epsg/wgs-84-nsidc-sea-ice-polar-stereographic-north/proj4js/)
proj4.defs('EPSG:3413', "+proj=stere +lat_0=90 +lat_ts=70 +lon_0=-45 +k=1 +x_0=0 +y_0=0 +ellps=WGS84 +datum=WGS84 +units=m +no_defs");
var transformedCoordinate = ol.proj.transform([85,85], 'EPSG:4326', 'EPSG:3413');
// results in [415170.5793604837, 348369.4800170395]

Related

How to convert 'Weird' ESRI Tile XYZ-Format to XYZ

I need to access a Esri REST service, which has a weird XYZ-Format. For example:
On a normal XYZ-Service, z is 14 where on this specific service, on the same height, z is 8.
Does anyone know how to convert them and use the "weird" one on OpenLayers?
This is the "normal" service:
...../15/17122/11081.png
And this the "weird" one:
...../8/458/170
They both are roughly for the same location, on equal height.
It is a custom tile grid for an EPSG:25832 projection.
The settings needed to set up the grid in OpenLayers can be found in https://karte.breitbandmessung.de/servertmp/rest/services/Mobilfunkversorgung/MonitoringPortal_DT_4G/Mapserver?f=pjson Only origin and resolutions are needed, but including extent will prevent out of range tiles being requested - the xmax of the fullExtent seems slightly too small and cuts off the eastern most edge of the country, so I made up an extent based on level 0 being 3 tiles wide
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<link rel="stylesheet" href="https://openlayers.org/en/v6.4.3/css/ol.css" type="text/css">
<script src="https://openlayers.org/en/v6.4.3/build/ol.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.6.1/proj4.js"></script>
<style>
html, body, .map {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="map" class="map"></div>
<script>
proj4.defs("EPSG:25832", "+proj=utm +zone=32 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs");
ol.proj.proj4.register(proj4);
var origin = [233184, 6120719];
var resolutions = [
1222.9948985513972,
611.4974492756991,
305.7487246378482,
152.87436231920458,
76.43718115960229,
38.21859057966118,
19.109295289886575,
9.5546476449433,
4.7773238224716374
];
//var extent = [280300, 5235800, 912300, 6106300];
var extent = [origin[0], origin[1] - 3 * 256 * resolutions[0], origin[0] + 3 * 256 * resolutions[0], origin[1]];
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM(),
}),
new ol.layer.Tile({
source: new ol.source.XYZ({
url: "https://karte.breitbandmessung.de/servertmp/rest/services/Mobilfunkversorgung/MonitoringPortal_DT_4G/Mapserver/tile/{z}/{y}/{x}",
projection: "EPSG:25832",
tileGrid: new ol.tilegrid.TileGrid({
origin: origin,
extent: extent,
resolutions: resolutions,
tileSize: [256, 256],
}),
}),
opacity: 0.5,
}),
],
view: new ol.View({
projection: "EPSG:25832",
})
});
map.getView().fit(extent);
</script>
</body>
</html>

draw point on map given coordinates with openlayers?

I'm trying to plot about 300 points on an openlayers map from a table of about 300 latitude and longitude cordinates. All I found on how to do it is the draw features from their website, but it can plot a point from a mouse click by the user, not automatically. Is there a way to plot a point on the map from the code?
Thank you.
To draw points (or any other geometry) on the map, you just need to,
Create a source, in this case a vector source, with the features you want to draw.
Create a layer, in this case a vector layer, with the source from step 1, and the style you prefer.
Add the layer to the map.
That is all you need to do. Take a look at the example I made for you, it generate 300 random points features and then follow the steps I describe before.
<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.2.1/css/ol.css" type="text/css">
<style>
.map {
height: 400px;
width: 100%;
}
</style>
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io#master/en/v6.2.1/build/ol.js"></script>
<title>Random Points From Code</title>
</head>
<body>
<h2>300 Random Points From Code</h2>
<div id="map" class="map"></div>
<script type="text/javascript">
// generate 300 random points features
const getRandomNumber = function (min, ref) {
return Math.random() * ref + min;
}
const features = [];
for (i = 0; i < 300; i++) {
features.push(new ol.Feature({
geometry: new ol.geom.Point(ol.proj.fromLonLat([
-getRandomNumber(50, 50), getRandomNumber(10, 50)
]))
}));
}
// create the source and layer for random features
const vectorSource = new ol.source.Vector({
features
});
const vectorLayer = new ol.layer.Vector({
source: vectorSource,
style: new ol.style.Style({
image: new ol.style.Circle({
radius: 2,
fill: new ol.style.Fill({color: 'red'})
})
})
});
// create map and add layers
const map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
vectorLayer
],
view: new ol.View({
center: ol.proj.fromLonLat([-75, 35]),
zoom: 2
})
});
</script>
</body>
</html>

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()
}),

Categories

Resources