Loading a static image as an openlayers map layer - javascript

I am trying to load an image into my openlayers canvas with the ultimate goal of loading a png file of our map legend as a layer on top of our map. I've been able to float the legend above the map with using div tags, but we need the legend to be captured within the canvas so that it can be saved by the user to a png file with the canvas.toBlob() functon.
I am not getting any errors that I can find, but my image is not appearing on top of my map.
my Javascript:
var pixelProjection = new ol.proj.Projection({
code: 'pixel',
units: 'pixels',
extent: [0, 0, 800, 600]
})
var mapLayer = new ol.layer.Tile({
source: new ol.source.OSM({
url: 'http://184.185.140.81/osm_tiles/{z}/{x}/{y}.png'
}),
opacity: 0.3,
isBaseLayer: false
});
var imageLayer = new ol.layer.Image({
source: new ol.source.ImageStatic({
//url: 'http://184.185.140.81/Futura_sample.PNG'
url: 'https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png',
imageSize: [800, 600],
projection: pixelProjection,
imageExtent: pixelProjection.getExtent()
})
})
var map = new ol.Map({
layers: [
mapLayer,
imageLayer
],
controls: ol.control.defaults().extend([
new ol.control.ScaleLine()
]),
target: 'map',
view: new ol.View({
center: ol.proj.transform([4.666389, 50.009167], 'EPSG:4326', 'EPSG:3857'),
zoom: 4,
minZoom: 1,
maxZoom: 20,
})
});
$('#exportMap').on('click', function() {
console.log('click');
canvas = document.getElementsByTagName('canvas')[0];
canvas.toBlob(function (blob) {
window.saveAs(blob, 'map.png');
})
});
HTML:
<div id="map"></div>
<div id="exportMapDiv">
<input type="button" id="exportMap" value="download map">
</div>
This code is just trying to test the functionality with a sample png from wikipedia as I don't have our legend prepared yet. The commented url: is another sample image I have saved to /var/www/html/Futura_sample.PNG
What is it I am doing wrong?
Edit: solved. I need to fix the projection of my image. It was rendering and projecting the image fine, but somewhere in another galaxy so to speak.

Related

OpenLayers 5 wms tiled map wrapping with Gall-Peters projection

With OL5 I'm trying to use a map with Gall-Peters projection with this definition:
var projname = 'EPSG:22';
var projdef = '+proj=cea +lon_0=0 +lat_ts=45 +x_0=0 +y_0=0 +ellps=WGS84 +units=m +no_defs';
var petersProjection = new Projection({
code: projname,
units: 'm',
extent: [-14192432.0000000000000000,-8984819.0000000000000000, 14192432.0000000000000000,8928365.0000000000000000]
});
proj4.defs(projname, projdef);
register(proj4);
GeoServer is used to serve the map as WMS and WMTS also in Gall-Peters projection.
In OL client the map is not wrapped across the 180° meridian. It only shows "one world".
When I switch the projection to EPSG:4326 or EPSG:3857 I get a continous wrapped map.
I'm stuck here.
Is something wrong with my projection definition?
Is OL only able to wrap with standard projections?
How can I get a wrapped map in Gall-Peters projection?
For reference here are my definitions of layer, view and map:
var basiskarte_source = new TileWMS({
url: geoserver_url,
serverType: 'geoserver',
params: {'FORMAT': 'image/png',
'VERSION': '1.1.1',
TILED: true,
LAYERS: 'eg:basiskarte',
tilesOrigin: -180 + "," + -90,
srs: 'EPSG:22'
},
projection : petersProjection
});
var wms_geoserver_tiled_layer =
new TileLayer({
title : 'gall-peters-map',
type : 'base',
visible : true,
source: basiskarte_source
});
var myview = new View({
center: fromLonLat([36.8394, -1.2743], petersProjection),
projection: projectionInUse,
zoom: 1,
rotation: deg2rad(180)
});
var map = new Map({
target: 'map',
layers: [
new LayerGroup({
title : 'Basiskarte',
layers: [wms_geoserver_tiled_layer]
})
],
view: myview
});

OpenLayers 4 prevent dragging outside bounds in all resolutoins

I need to constrain the map to only drag within the map view but It also needs to work across multiple resolutions:
var extent = [0, 0, 1685, 895];
var projection = new ol.proj.Projection({
units: 'pixels',
extent: extent
});
var map = new ol.Map({
layers: [
new ol.layer.Image({
source: new ol.source.ImageStatic({
url: 'assets/img/map.png',
projection: projection,
imageExtent: [0, 0, 1685, 895]
})
})
],
target: 'map',
view: new ol.View({
projection: projection,
center: ol.extent.getCenter(extent),
zoom: 3,
maxZoom: 5,
minZoom: 3
})
});

How to animate Image png with openlayers3

I need to implement a function with openlayers-3.
Description:There are a series of images .png. I need to play them like a animation.I set the image source as ImageStatic,but When I set the current image visible is false ,it doesn't work. the visible property seems like not work.
Code:
var extent = [0, 0, 418, 600];
var projection = new ol.proj.Projection({
code: 'xkcd-image',
units: 'pixels',
extent: extent
});
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
}),
new ol.layer.Group({
layers: [
new ol.layer.Image({
source: new ol.source.ImageStatic({
url: 'http://localhost:2265/images3/test2.png',
projection: projection,
imageExtent: extent,
})
}),
new ol.layer.Image({
source: new ol.source.ImageStatic({
url: 'http://localhost:2265/images2/test1.png',
projection: projection,
imageExtent: extent,
})
})
]
})
],
target: 'map',
view: new ol.View({
projection: projection,
center: ol.extent.getCenter(extent),
zoom: 2,
maxZoom: 8
})
});
var layers = map.getLayers().getArray();
var frame = 1;
setInterval(function () {
layers[frame].setVisible = false;
frame = (frame + 1) % 2;
layers[frame].setVisible = true;
},500);
map.layers[1] is a group, to get the image layers try:
var layers = map.getLayers().getArray()[1].getLayers().getArray();
You can also do 'real' animation by rendering directly to the canvas:
http://openlayers.org/en/latest/examples/feature-move-animation.html
http://openlayers.org/en/latest/examples/flight-animation.html

openlayers 3 - Load TileLayer with highest zoom level tiles but display at all zoom levels

Is is possible to load a Tile layer from a TileImage source with tiles in its highest resolution (zoom) for a specific extent and have these tiles show for all zoom levels. I have high resolution imagery I wish to show as a layer above another Tile layer such as Bing or OSM.
Example source
var source = new ol.source.TileImage({
projection: 'EPSG:900913',
tileGrid: new ol.tilegrid.TileGrid({
projection: 'EPSG:900913',
extent: projectionExtent,
//extent: ol.proj.transformExtent([-83.7893967, 42.851353, -83.7855987, 42.849371], "EPSG:4326", "EPSG:900913"),
resolutions: resolutions,
tileSize:[pictometryImageSize, pictometryImageSize]
}),
tileUrlFunction: function(tileCoord, pixelRatio, projection){
var zoom = tileCoord[0];
console.log(zoom)
if(zoom == 21){
var tileGrid = this.getTileGrid();
var center = ol.proj.transform(ol.extent.getCenter(tileGrid.getTileCoordExtent(tileCoord)),"EPSG:900913", "EPSG:4326");
return 'www.myrealtileurl;
}
//return undefined;
//return 'https://dummy.com';
},
minZoom: 0,
maxZoom: 21
});
I hope I understand you correctly. First, you can restrict layer extent with extent. Second, you can lock zoom with maxZoom and minZoom properties. OpenLayers will resize tiles on his own. Here is an example, where ArcGIS tile layer is locked in extent and zoom:
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({ source: new ol.source.OSM() }),
new ol.layer.Tile({
extent: ol.proj.transformExtent([-110, 42, -100, 48], "EPSG:4326", "EPSG:3857"),
source: new ol.source.XYZ({
maxZoom: 6,
minZoom: 6,
url: 'http://server.arcgisonline.com/ArcGIS/rest/services/' +
'World_Topo_Map/MapServer/tile/{z}/{y}/{x}'
})
})
],
view: new ol.View({
center: ol.proj.fromLonLat([-105.89, 45.09]),
zoom: 6
})
});

how to add markers with OpenLayers 3

I'm trying to add makers on a OpenLayers 3 map.
The only example I have found is this one in the OpenLayers example list.
But the example uses ol.Style.Icon instead of something like OpenLayers.Marker in OpenLayers 2.
First Question
The only difference would be that you have to set the image Url but is it the only way to add a marker?
Also OpenLayers 3 doesn't seem to come with marker images so it would make sense if there's no other way than ol.Style.Icon
Second Question
It would be really nice if someone could give me an example of a function to add markers or icons after the map is loaded.
From what I understand in the example, they create a layer for the icon
var iconFeature = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform([-72.0704, 46.678], 'EPSG:4326', 'EPSG:3857')),
name: 'Null Island',
population: 4000,
rainfall: 500
});
var iconStyle = new ol.style.Style({
image: new ol.style.Icon(/** #type {olx.style.IconOptions} */ ({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
opacity: 0.75,
src: 'data/icon.png'
}))
});
iconFeature.setStyle(iconStyle);
var vectorSource = new ol.source.Vector({
features: [iconFeature]
});
var vectorLayer = new ol.layer.Vector({
source: vectorSource
});
Then they set the icon layer when they initialize the map
var map = new ol.Map({
layers: [new ol.layer.Tile({ source: new ol.source.OSM() }), vectorLayer],
target: document.getElementById('map'),
view: new ol.View2D({
center: [0, 0],
zoom: 3
})
});
If I want to add many markers, do I have to create 1 layer for each marker?
How could I add many markers to a layer? I can't figure out how this part would look
like
var vectorSource = new ol.source.Vector({
features: [iconFeature]
});
var vectorLayer = new ol.layer.Vector({
source: vectorSource
});
Thank you
Q1. Markers are considered deprecated in OpenLayers 2, though this isn't very obvious from the documentation. Instead, you should use an OpenLayers.Feature.Vector with an externalGraphic set to some image source in its style. This notion has been carried over to OpenLayers 3, so there is no marker class and it is done as in the example you cited.
Q2. The ol.source.Vector takes an array of features, note the line, features: [iconFeature], so you would create an array of icon features and add features to that, eg:
var iconFeatures=[];
var iconFeature = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform([-72.0704, 46.678], 'EPSG:4326',
'EPSG:3857')),
name: 'Null Island',
population: 4000,
rainfall: 500
});
var iconFeature1 = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform([-73.1234, 45.678], 'EPSG:4326',
'EPSG:3857')),
name: 'Null Island Two',
population: 4001,
rainfall: 501
});
iconFeatures.push(iconFeature);
iconFeatures.push(iconFeature1);
var vectorSource = new ol.source.Vector({
features: iconFeatures //add an array of features
});
var iconStyle = new ol.style.Style({
image: new ol.style.Icon(/** #type {olx.style.IconOptions} */ ({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
opacity: 0.75,
src: 'data/icon.png'
}))
});
var vectorLayer = new ol.layer.Vector({
source: vectorSource,
style: iconStyle
});
Obviously, this could be more elegantly handled by putting all of the ol.Feature creation inside a loop based on some data source, but I hope this demonstrates the approach. Note, also, that you can apply a style to the ol.layer.Vector so that it will be applied to all features being added to the layer, rather than having to set the style on individual features, assuming you want them to be the same, obviously.
EDIT: That answer doesn't seem to work. Here is an updated fiddle that works by adding the features (icons) to the empty vector source in a loop, using vectorSource.addFeature and then adds the whole lot to the layer vector afterwards. I will wait and see if this works for you, before updating my original answer.
there's a good tutorial at: http://openlayersbook.github.io
not tested but may helpful
var features = [];
//iterate through array...
for( var i = 0 ; i < data.length ; i++){
var item = data[i]; //get item
var type = item.type; //get type
var longitude = item.longitude; //coordinates
var latitude = item.latitude;
/*....
* now get your specific icon...('..../ic_customMarker.png')
* by e.g. switch case...
*/
var iconPath = getIconPath(type);
//create Feature... with coordinates
var iconFeature = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform([longitude, latitude], 'EPSG:4326',
'EPSG:3857'))
});
//create style for your feature...
var iconStyle = new ol.style.Style({
image: new ol.style.Icon(/** #type {olx.style.IconOptions} */ ({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
opacity: 0.75,
src: iconPath
}))
});
iconFeature.setStyle(iconStyle);
features.push(iconFeature);
//next item...
}
/*
* create vector source
* you could set the style for all features in your vectoreSource as well
*/
var vectorSource = new ol.source.Vector({
features: features //add an array of features
//,style: iconStyle //to set the style for all your features...
});
var vectorLayer = new ol.layer.Vector({
source: vectorSource
});
map.addLayer(vectorLayer);
var exampleLoc = ol.proj.transform(
[131.044922, -25.363882], 'EPSG:4326', 'EPSG:3857');
var map = new ol.Map({
target: 'map',
renderer: 'canvas',
view: new ol.View2D({
projection: 'EPSG:3857',
zoom: 3,
center: exampleLoc
}),
layers: [
new ol.layer.Tile({source: new ol.source.MapQuest({layer: 'osm'})})
]
});
map.addOverlay(new ol.Overlay({
position: exampleLoc,
element: $('<img src="resources/img/marker-blue.png">')
.css({marginTop: '-200%', marginLeft: '-50%', cursor: 'pointer'})
.tooltip({title: 'Hello, world!', trigger: 'click'})
}));
map.on('postcompose', function(evt) {
evt.vectorContext.setFillStrokeStyle(
new ol.style.Fill({color: 'rgba(255, 0, 0, .1)'}),
new ol.style.Stroke({color: 'rgba(255, 0, 0, .8)', width: 3}));
evt.vectorContext.drawCircleGeometry(
new ol.geom.Circle(exampleLoc, 400000));
});
var exampleKml = new ol.layer.Vector({
source: new ol.source.KML({
projection: 'EPSG:3857',
url: 'data/example.kml'
})
});
map.addLayer(exampleKml);
We just finished updating our website NUFOSMATIC from ol2 to ol6. Both the ol2 and ol3 code is on the site. This includes Matt Walker's ol-layerswitcher https://github.com/walkermatt replacing the missing ol2 layerswitcher. We actually updated three map applications; HEATMAP replaces the Patrick Wied (http://www.patrick-wied.at) ol2 heatmap with the native ol6 heatmap.
Only took 6 days. Wonder why we waited this long... oh, yeah, we have day jobs...

Categories

Resources