I'm new at OpenLayers3 and trying to build a simple form that centers my map to a given spot. The problem is that i'm always landing somwhere near the south-pole. here is my code:
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM
})
],
view: new ol.View({
center: [0,0],
zoom: 8
})
search.addEventListener("change", searchChanged);
function searchChanged()
{
var searchVal = encodeURIComponent(search.value);
var geocode = 'http://open.mapquestapi.com/nominatim/v1/search.php?key=KEY&format=json&q=' + searchVal;
$.getJSON(geocode, function(data)
{
if(!data)
{
return;
}
map.getView().setCenter(ol.proj.transform([data[0].lon, data[0].lat], 'EPSG:4326', 'EPSG:3857'));
}
);
}
Make sure your coordinate will not be treated as string:
ol.proj.transform([parseFloat(data[0].lon), parseFloat(data[0].lat]), 'EPSG:4326', 'EPSG:3857')
Better, debug it:
var coord = ol.proj.transform([parseFloat(data[0].lon), parseFloat(data[0].lat]), 'EPSG:4326', 'EPSG:3857');
console.info(coord);
Related
I have an OL3 web application and I am wondering if it is possible to include URL parameters (such as coordinate values) for which the application can parse and open up at a specific location?
For example http://mywebsiteaddress?x=longitudevalue&y=latitudevalue
Is this something that can be done using OL3?
Sure, see: http://openlayers.org/en/latest/examples/permalink.html for an example (uses an anchor instead of url parameters but the idea is the same).
I did not like the openlayers permalink example because it uses map units and not well-known latitudes and longitudes. Sp I wrote my own code to hand over latlon coordinates, zoom and set a marker to it:
function getURLParameter(name) {
return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search) || [null, ''])[1].replace(/\+/g, '%20')) || null;
}
var mzoom=12;
var mlat = Number(getURLParameter('mlat'));
var mlon = Number(getURLParameter('mlon'));
var mzoom = Number(getURLParameter('zoom'));
var marker = 1
if (mlat == 0 || mlon == 0) {
mlat = 51.5; mlon = 7.0; mzoom=12; marker=0 //Default location
}
if (mzoom == 0 ) { mzoom=12 //Default zoom
}
var container = document.getElementById('popup');
var content = document.getElementById('popup-content');
var closer = document.getElementById('popup-closer');
closer.onclick = function() {
container.style.display = 'none';
closer.blur();
return false;
};
var overlayPopup = new ol.Overlay({
element: container
});
var expandedAttribution = new ol.control.Attribution({
collapsible: false
});
var map = new ol.Map({
controls: ol.control.defaults({attribution:false}).extend([
expandedAttribution
]),
target: document.getElementById('map'),
renderer: 'canvas',
overlays: [overlayPopup],
layers: layersList,
view: new ol.View({
center: ol.proj.fromLonLat([mlon, mlat]),
zoom: mzoom,
maxZoom: 18, minZoom: 8
})
});
if (marker == 1) {
var vectorLayer = new ol.layer.Vector({
source:new ol.source.Vector({
features: [new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform([parseFloat(mlon), parseFloat(mlat)], 'EPSG:4326', 'EPSG:3857')),
})]
}),
style: new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 0.5],
anchorXUnits: "fraction",
anchorYUnits: "fraction",
src: "marker.svg"
})
})
});
map.addLayer(vectorLayer);
}
I used the output of the qgis2web plugin and modified the file qgis2web.js as above.
I have problem how to coonnect a offline tileLayer in ol3.
This ismy code:
var tileLayer = new ol.source.XYZ("offline",
"Tiles/${x}/${y}/${z}.png", { numZoomLevels: 18, isBaseLayer: true });
It was work fine in ol2 with OpenLayers.Layer.OSM
I spend some time looking for help, but I found a wall.
First you define a tile layer (ol.layer.Tile) and inside this you define the source.
var map = new ol.Map({
target: 'map',
view: new ol.View({
zoom: 1,
center: [0, 0]
}),
layers: [
new ol.layer.Tile({
source: new ol.source.XYZ({
url: 'Tiles/{x}/{y}/{z}.png',
maxZoom: 18
})
})
]
});
Edited the url of the ol.source.XYZ object, moved out the $ chars. Maybe now your tiles will load.
I've created a tile set of an image using MapTiler. MapTiler generates a OL 2 script that centers the tiled image in the viewing window with the following code:
var map, layer;
var mapBounds = new OpenLayers.Bounds(0.000000, -9350.000000, 14450.000000, 0.000000);
var mapMinZoom = 0;
var mapMaxZoom = 6;
var mapMaxResolution = 1.000000;
var gridBounds = new OpenLayers.Bounds(0.000000, -9350.000000, 14450.000000, 0.000000);
function init() {
var options = {
controls: [],
maxExtent : gridBounds,
minResolution: mapMaxResolution,
numZoomLevels: mapMaxZoom+1
};
map = new OpenLayers.Map('map', options);
layer = new OpenLayers.Layer.XYZ( "MapTiler layer", "${z}/${x}/${y}.png", {
transitionEffect: 'resize',
tileSize: new OpenLayers.Size(256, 256),
tileOrigin: new OpenLayers.LonLat(gridBounds.left, gridBounds.top)
});
map.addLayer(layer);
map.zoomToExtent(mapBounds);
I want to use OL3 to display the tiled map but do not know how to implement equivalent OL3 methods to achieve this. Using the following script I can display the tiled image but I cannot figure out how to center the tiles to in the view.
map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM({
url: map_path + '{z}/{x}/{y}.png'
})
})
],
view: new ol.View({
center: [0, 0],
zoom: 2
})
});
I've inspected the map extent which turns out to be:
-20037508.342789244,-20037508.342789244,20037508.342789244,20037508.342789244
My tiled image extent is given in the OL2 code, but I don't known how to use this information in OL3. I think it might have something to do with a transformation or fitExtent but without further direction, it seems I'm just guessing at what to do.
You will have to create a pixel projection for this to work properly. Then you can use fit (replacement for the former fitExtent), as you already suspected, to zoom to the full extent of the image.
The whole OpenLayers 2 code translated to OpenLayers 3 would look like this:
var mapBounds = [0.000000, -9350.000000, 14450.000000, 0.000000];
var mapMaxZoom = 6;
var gridBounds = [0.000000, -9350.000000, 14450.000000, 0.000000];
var projection = new ol.proj.Projection({
code: 'pixels',
units: 'pixels',
extent: gridBounds
});
var map = new ol.Map({
target: 'map',
view: new ol.View({
extent: mapBounds,
projection: projection
})
});
var layer = new ol.layer.Tile({
source: new ol.source.XYZ({
url: '{z}/{x}/{y}.png',
projection: projection,
maxZoom: mapMaxZoom
})
});
map.addLayer(layer);
map.getView().fit(mapBounds, map.getSize());
I'm showing the mouse position in OpenLayers 3 with the following control
var mousePositionControl = new ol.control.MousePosition({
coordinateFormat: ol.coordinate.createStringXY(2),
projection: 'EPSG:4326',
undefinedHTML: ' '
});
But the result shows the mouse position as Lon,Lat rather than Lat,Lon.
Here's a jsfiddle example.
How can I reverse the order so that it's Lat,Lon?
What works for me to add a variety of controls incl Lat, Long is:
var controls = [
new ol.control.Attribution(),
new ol.control.MousePosition({
projection: 'EPSG:4326',
coordinateFormat: function(coordinate) {
return ol.coordinate.format(coordinate, '{y}, {x}', 4);
}
}),
new ol.control.ScaleLine(),
new ol.control.Zoom(),
new ol.control.ZoomSlider(),
new ol.control.ZoomToExtent(),
new ol.control.FullScreen()
];
(modified from the book of openlayers 3)
You change your coordinateFormat - "standard function" to a custom function:
var myFormat = function(dgts)
{
return (
function(coord1) {
var coord2 = [coord1[1], coord1[0]];
return ol.coordinate.toStringXY(coord2,dgts);
});
}
var mousePositionControl = new ol.control.MousePosition({
coordinateFormat: myFormat(2), // <--- change here
projection: 'EPSG:4326',
className: 'custom-mouse-position',
target: document.getElementById('mouse-position'),
undefinedHTML: ' '
});
see your modified fiddle
An alternative:
var template = 'LatLon: {y}, {x}';
var mousePositionControl = new ol.control.MousePosition({
coordinateFormat: function(coord) {return ol.coordinate.format(coord, template, 2);},
projection: 'EPSG:4326',
undefinedHTML: ' '
});
Also helpful to display in Degrees, Minutes, Seconds:
controls: ol.control.defaults().extend([
new ol.control.ScaleLine({
units: 'nautical'
}),
new ol.control.MousePosition({
coordinateFormat: function(coord) {
return ol.coordinate.toStringHDMS(coord);
},
projection: 'EPSG:4326',
className: 'custom-mouse-position',
target: document.getElementById('mouse-position'),
undefinedHTML: ' '
})
]),
Works in OpenLayers 3.7.0. Using proj4js to reproject coordinates to a different projection due to map view being in 'EGPS:3857':
var proj1 = proj4.defs('EPSG:4326');
var proj2 = proj4.defs('EPSG:3857');
var myFormat = function(digits) {
return (
function(originalCoordinates) {
var reprojectedCoordinates = proj4(proj2, proj1).forward(originalCoordinates);
var switchedCoordinates = [reprojectedCoordinates[1], reprojectedCoordinates[0]];
return ol.coordinate.toStringXY(switchedCoordinates, digits);
}
);
}
var mousePositionControl = new ol.control.MousePosition({
coordinateFormat: mojFormat(10),
projection: 'ESPG:4326',
undefinedHTML: ' '
});
// map.addControl(mousePositionControl); //equivalent to setMap
mousePositionControl.setMap(map);
I produced a zoomify tileset from some digitized map image and would now like to use OL3 to display that map on a Website. However, my script currently fails loading that map from a local file uri (later, in production, I will upload the tiles on some Web Server and reference the tiles using HTTP). Here is what I have so far:
var url = 'file:///home/user/map_zoomfiy/';
var imgWidth = 17244;
var imgHeight = 9684;
var imgCenter = [imgWidth / 2, - imgHeight / 2];
var proj = new ol.proj.Projection({
code: 'ZOOMIFY',
units: 'pixels',
extend: [0, 0, imgWidth, imgHeight]
});
var source = new ol.source.Zoomify({
url: url,
size: [imgWidth, imgHeight],
crossOrigin: 'anonymous'
});
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: source
})
],
view: new ol.View({
projection: proj,
center: imgCenter,
zoom: 1
})
});
</script>
Any ideas why this fails? Thx.
It's not right way e.g https://developer.mozilla.org/en-US/docs/WebGuide/API/File_System/Introduction#file
I don't see why you do not make a local server instead of fighting to access your file with local url.
Some times ago, I compiled some recipes to do so.
Open your command line, go to your code root dir and follow recipes depending of your favorite programming language.
If the tiles are in a subdirectory (e.g., tiles_zoomify) the following should work
var url = 'tiles_zoomify/';
var imgWidth = 17244;
var imgHeight = 9684;
var imgCenter = [imgWidth / 2, - imgHeight / 2];
var proj = new ol.proj.Projection({
code: 'ZOOMIFY',
units: 'pixels',
extend: [0, 0, imgWidth, imgHeight]
});
var source = new ol.source.Zoomify({
url: url,
size: [imgWidth, imgHeight],
crossOrigin: 'anonymous'
});
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: source
})
],
view: new ol.View({
projection: proj,
center: imgCenter,
zoom: 1
})
});