I have a pretty well integrated OpenLayers map that I want to add photos from the Panoramio API to. Unfortunately, it seems both API's are under documented on this subject. I found one great tutorial here http://www.gisandchips.org/2010/05/04/openlayers-y-panoramio/ but as I am new to all of this, could be why I cannot complete this on my own. I feel like even using this tutorial I have a lot of blank spaces in my mind and not to mention, the photos are NOT appearing on my map :-/
Here is my portion of the code that demonstrates my use of that tutorial and what I have attempted so far:
var url = "http://www.panoramio.com/map/get_panoramas.php";
var parameters = {
order: 'popularity',
set: 'full',
from: 0,
to: 20,
minx: 84.05,
miny: 31.36,
maxx: 91.89,
maxy: 32.30,
size: 'thumbnail'
} //end parameters
OpenLayers.loadURL(url, parameters, this, displayPhotos);
function displayPhotos(response) {
var json = new OpenLayers.Format.JSON();
var panoramio = json.read(response.responseText);
var features = new Array(panoramio.photos.length);
for (var i = 0; i < panoramio.photos.length; i++) {
var upload_date = panoramio.photos[i].upload_date;
var owner_name = panoramio.photos[i].owner_name;
var photo_id = panoramio.photos[i].photo_id;
var longitude = panoramio.photos[i].longitude;
var latitude = panoramio.photos[i].latitude;
var pheight = panoramio.photos[i].height;
var pwidth = panoramio.photos[i].width;
var photo_title = panoramio.photos[i].photo_title;
var owner_url = panoramio.photos[i].owner_url;
var owner_id = panoramio.photos[i].owner_id;
var photo_file_url = panoramio.photos[i].photo_file_url;
var photo_url = panoramio.photos[i].photo_url;
var fpoint = new OpenLayers.Geometry.Point(longitude, latitude);
var attributes = {
'upload_date': upload_date,
'owner_name': owner_name,
'photo_id': photo_id,
'longitude': longitude,
'latitude': latitude,
'pheight': pheight,
'pwidth': pwidth,
'pheight': pheight,
'photo_title': photo_title,
'owner_url': owner_url,
'owner_id': owner_id,
'photo_file_url': photo_file_url,
'photo_url': photo_url
} //end attributes
features[i] = new OpenLayers.Feature.Vector(fpoint, attributes);
} //end for
var panoramio_style2 = new OpenLayers.StyleMap(OpenLayers.Util.applyDefaults({
pointRadius: 7,
fillColor: "red",
fillOpacity: 1,
strokeColor: "black",
externalGraphic: "panoramio-marker.png"
}, OpenLayers.Feature.Vector.style["default"]));
var vectorPano = new OpenLayers.Layer.Vector("Panoramio Photos", {
styleMap: panoramio_style2
});
vectorPano.addFeatures(features);
map.addLayer(vectorPano);
} //end displayPhotos
In my mind this code should work perfectly. Giving me a result of some Panoramio thumbnails on my slippy map. Unfortunately it seems that the layer is there, but blank..When I look at the response text in Firebug I can see that the JSON is returned with attributes of photos from Panoramio, in the location I have specified (Tibet). I appreciate your help and time to consider my issues.
Thank you,
elshae
I don't know how proficient you are in OpenLayers, but the project is certainly not underdocumented. There is an extensive api documentation and also numerous examples that should help to get you started.
But now back to your problem: likely, this is a projection issue. Panoramio returns WSG-84 (GPS) Coordinates for all the photos it found, and the openstreetmap baselayer of your map is in Spherical Mercator projection ('EPSG:900913').
So you have to convert the coordinates from WSG-84 to Spherical Mercator using something like
var curPic = panoramio.photos[i];
var panLonLat = new OpenLayers.LonLat(curPic.longitude, curPic.latitude);
panLonLat.transform(new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection('EPSG:900913'));
and then use the converted point for your geometry
Related
I am currently working on a web application where I'm trying to display a heat map using the library called Leaflet.heat. It works with the Leaflet Javascript library to create an overlay heat map that looks pretty good. I feel like I'm pretty much there but having one last bit of trouble with array format and can't figure out what is wrong. Let me share the code that I have right now.
var mymap;
var marker = [];
var heatMapArr = [];
window.onload = function() {
alert("in initial func");
uponPageLoadDefault();
};
function uponPageLoadDefault()
{
//initial default page load
var branches = new L.LayerGroup();
var items = JSON.parse('${branches}');
var j = 0;
for(var i = 0; i < items.length; i++)
{
var LamMarker = new L.marker([items[i].lat, items[i].lon]);
//GOT RID OF FUNCTION CALL.
var heatMapPoint = {
lat: items[i].lat,
lon: items[i].lon,
intensity: items[i].tranCount
};
heatMapArr.push(heatMapPoint);
LamMarker.bindPopup("<b>" + items[i].branchName + "</b><br>" + items[i].branchAdd + "</br><br>" + items[i].branchCity + "</br><br>" + items[i].branchSt + "</br><br>" + items[i].branchZip + "</br><br>TranCount: " + items[i].tranCount).addTo(branches);
marker.push(LamMarker);
}
mbAttr = 'Map data © OpenStreetMap contributors, ' +
'CC-BY-SA, ' +
'Imagery © Mapbox',
mbUrl = 'https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoidGFzdHlicm93bmllcyIsImEiOiJjaXgzZWxkaHowMWZhMnlvd2wzNHllaGwxIn0.0RSZEhtR0OBLMbwjqFfBkg';
var outdoors = L.tileLayer(mbUrl, {id: 'mapbox.outdoors', attribution: mbAttr});
var heatmap = L.heatLayer(heatMapArr, {radius: 6, blur: 8,maxZoom: 8});
var map = L.map('map', {
center: [39.73, -104.99],
zoom: 10,
layers: [outdoors, branches, heatmap]
});
var baseLayers = {
"Outdoors": outdoors
};
var overlays = {
"Branches": branches,
"HeatMap": heatmap
};
L.control.layers(baseLayers, overlays).addTo(map);
So basically I am trying to use the heat map display as a possible overlay that the user can select. The Leaflet-heat library tutorial is located at https://github.com/Leaflet/Leaflet.heat/ and it explains what needs to be done in order for the library to work.
Anyway, I have a list of items with latitude, longitude, and intensity amount, so I'm trying to use that, its called items. I iterate through that, pushing the select information into my heat map array. At this point I should be almost all set besides adding the overlays and creating the map. When I run the program, the map displays but the overlay icon is absent so there is an issue.
In the website tutorial they use a separate Javascript file which has an array of objects to create their heat map. I tried this with my program and then everything worked, which quickly led me to believe there's a problem with my array of objects, probably some minor formatting thing.......I am using another function to create an object with the data I have, so it will be in the same format as the website example.
I tried to use alert and other statements and compare my array to theirs but it hasn't yielded anything useful so I wanted to post my issue here on Stack to get some feedback from others on what could be wrong. I think its something really small that I may not be seeing.
Any feed back is greatly appreciated and certainly let me know if there's any questions.
Thanks!
I'm migrating from leaflet and back then if i needed the map bound i used the following code:
var b = map.getBounds();
$scope.filtromapa.lat1 = b.getSouth();
$scope.filtromapa.lat2 = b.getNorth();
$scope.filtromapa.lng1 = b.getWest();
$scope.filtromapa.lng2 = b.getEast();
Those values where valid latitude/longitude positions therefore i could send it to my backend and query any position inside this area.
How can i do that using openlayers?
for now all i have is:
var b = map.getView().calculateExtent(map.getSize());
however the positions aren't valid latitude/longitude positions.
I'm using openlayers 3.19.1
Following the answer at https://gis.stackexchange.com/questions/122250/how-to-get-the-feature-location-in-openlayers-v3 (and its assumptions)
var currentExtent = map.getView().calculateExtent(map.getSize()),
TLpoint = ol.extent.getTopLeft( currentExtent ),
BRpoint = ol.extent.getBottomRight( currentExtent ),
TLcoords = ol.proj.transform( TLpoint, 'EPSG:3857', 'EPSG:4326' ),
BRcoords = ol.proj.transform( BRpoint, 'EPSG:3857', 'EPSG:4326' );
I want to get the intersection point of two polylines in leaflet.
I have two lines as given below :-
var latlng1 = L.latLng(-7.9375, 4.46354);
var latlng2 = L.latLng(-7.96875, 16.11979);
var latlongs1 = [ latlng1, latlng2 ];
var polyline1 = L.polyline(latlongs1, {
color : 'red'
}).addTo(map);
var latlng3 = L.latLng(-3.5625, 9.31719);
var latlng4 = L.latLng(-12.125, 9.50469);
var latlongs2 = [ latlng3, latlng4 ];
var polyline2 = L.polyline(latlongs2, {
color : 'blue'
}).addTo(map);
I can get the bounds and latlongs of the endpoints of these lines. I can't get the contiguous array of all latlongs of line. Is there any way to get that ?
If you don't want to code all the logic, there is a small and easy to use library called Turf that provides several geoprocessing algorithms. You can even use just one of the algorithms mostly independent of the rest of the library.
The lineIntersects module does exactly what you want.
var intersection = turf.lineIntersect(polyline1.toGeoJSON(), polyline2.toGeoJSON());
var intersectionCoord = intersection.features[0].geometry.coordinates;
Also you can check the source code of the module for inspiration.
Is it possible to have a layer made up of a mosaic of custom images?
I've been only able to get a single custom image on a given layer via OpenLayers.Layer.Image. Essentially, if I could find a way to specify custom images for the tiles of a given layer, then my problem would be solved.
I have tried various combinations of OpenLayers.Tile, OpenLayers.Tile.Image, OpenLayers.Layer and OpenLayers.Layer.Grid but haven't been able to things working.
The basic flow I follow is:
var map = new OpenLayers.Map('map');
var layer = new <OpenLayers.Layer | OpenLayers.Layer.Grid> (<parameters>);
var tile1 = new <OpenLayers.Tile | OpenLayers.Tile.Image> (<parameters>);
map.addLayer(layer);
map.zoomToMaxExtent();
Specific examples of how I initialize each constructor are provided below.
Regarding OpenLayers.Layer.Grid, I'm actually not sure what to specify for the url and params constructor parameters.
Any advice on whether this works and/or if I'm on the right track would be greatly appreciated.
OpenLayers.Layer
var layer = new OpenLayers.Layer(
'layer_name',
{
isBaseLayer: true
}
);
OpenLayers.Layer.Grid
var layer = new OpenLayers.Layer.Grid(
'layer_name',
?url?,
?params?
);
OpenLayers.Tile
var layer = new OpenLayers.Tile(
layer_name,
new OpenLayers.Pixel(0,0),
new OpenLayers.Bounds(-1,-1,1,1),
'square1.jpg',
new OpenLayers.Size(300,300)
);
OpenLayers.Tile.Image
var layer = new OpenLayers.Tile.Image(
layer_name,
new OpenLayers.Pixel(0,0),
new OpenLayers.Bounds(-1,-1,1,1),
new OpenLayers.Size(300,300),
{
url: 'square1.jpg'
}
);
Have you tried Zoomify layer? Here's the example. It allows you to load in the map all images from a given directory, named in the form {z}-{x}-{y}.jpg, where {z} is the zoom level.
If you need to break up an image into smaller tiles, I suggest using this free MapTiler software, which will create the tiles for as many zoom levels as you need.
You can create a map layer of image tiles using a TMS Layer:
var layer = new OpenLayers.Layer.TMS("TMS Layer","",
{url: '', serviceVersion: '.', layername: '.', alpha: true,
type: 'png', getURL: getTileURL
}
);
map.addLayer(layer);
The getTileURL function is used by the TMS layer to find the tiled images to display. This function assumes that the images are stored in a hierarchical structure like the one created by MapTiler.
Ex: img/tiles/7/4/1.png is the image that is 5th from the left and 2nd from the bottom of zoom level 7.
function getTileURL(bounds)
{
var res = this.map.getResolution();
var x = Math.round((bounds.left - this.maxExtent.left) / (res * this.tileSize.w));
var y = Math.round((bounds.bottom - this.maxExtent.bottom) / (res * this.tileSize.h));
var z = this.map.getZoom();
var path = "img/tiles/" + z + "/" + x + "/" + y + "." + this.type;
var url = this.url;
if (url instanceof Array)
{
url = this.selectUrl(path, url);
}
return url + path;
}
I have a connection to a database(db). I am getting the lon, lat and name from the db and stroing them:
while ($row_ChartRS = mysql_fetch_array($sql1))
{
$latitude=$row_ChartRS['latitude'];
$longitude=$row_ChartRS['longitude'];
$bus_name =$row_ChartRS['short_name'];
//echo $latitude.'--'.$longitude.'<br>';
echo $bus_name;
I then create a map to display the data. The markers are working fine for all lat, lon locations. Code:
function init()
{
projLonLat = new OpenLayers.Projection("EPSG:4326"); // WGS 1984
projMercator = new OpenLayers.Projection("EPSG:900913"); // Spherical Mercator
overviewMap = new OpenLayers.Control.OverviewMap();
//adding scale ruler
scale = new OpenLayers.Control.ScaleLine();
scale.geodesic = true; // get the scale projection right, at least on small
map = new OpenLayers.Map('demoMap',
{ controls: [ new OpenLayers.Control.Navigation(), // direct panning via mouse drag
new OpenLayers.Control.Attribution(), // attribution text
new OpenLayers.Control.MousePosition(), // where am i?
new OpenLayers.Control.LayerSwitcher(), // switch between layers
new OpenLayers.Control.PanZoomBar(), // larger navigation control
scale,
overviewMap // overview map
]
}
);
map.addLayer(new OpenLayers.Layer.OSM.Mapnik("Mapnik"));
map.addLayer(new OpenLayers.Layer.OSM.Osmarender("Osmarender"));
//Create an explicit OverviewMap object and maximize its size after adding it to the map so that it shows
//as activated by default.
overviewMap.maximizeControl();
//Adding a marker
markers = new OpenLayers.Layer.Markers("Vehicles");
map.addLayer(markers);
vectorLayer = new OpenLayers.Layer.Vector('Routes');
map.addLayer(vectorLayer);
for (k in Locations)
{
//adding a popup for the marker
var feature = new OpenLayers.Feature(markers, new OpenLayers.LonLat(Locations[k].lon, Locations[k].lat).transform(projLonLat,projMercator));
//true to close the box
feature.closeBox = true;
feature.popupClass = new OpenLayers.Class(OpenLayers.Popup.AnchoredBubble,
{
//create the size of the box
'autoSize': true,
'maxSize': new OpenLayers.Size(100,100)
});
//add info into box
for (z in names)
{
feature.data.popup = new OpenLayers.Feature(new OpenLayers.LonLat(names[z]).transform(projLonLat,projMercator));
}
//puts a scroll button on box to scroll down to txt
//feature.data.overflow = "auto";
marker = feature.createMarker();
marker.display(true);
markerClick = function (evt) {
if (this.popup == null) {
this.popup = this.createPopup(this.closeBox);
map.addPopup(this.popup);
this.popup.show();
} else {
this.popup.toggle();
}
currentPopup = this.popup;
OpenLayers.Event.stop(evt);
};
marker.events.register("mousedown", feature, markerClick);
markers.addMarker(marker);
map.setCenter(new OpenLayers.LonLat(Locations[k].lon, Locations[k].lat).transform(projLonLat,projMercator), zoom);
var lonLat1 = new OpenLayers.LonLat(Locations[k].lon,Locations[k].lat).transform(new OpenLayers.Projection('EPSG:4326'), map.getProjectionObject());
var pos2=new OpenLayers.Geometry.Point(lonLat1.lon,lonLat1.lat);
points1.push(pos2);
//Uncomment to put boxes in when map opens
//feature.popup = feature.createPopup(feature.closeBox);
//map.addPopup(feature.popup);
//feature.popup.show()
}
var lineString = new OpenLayers.Geometry.LineString(points1);
var lineFeature = new OpenLayers.Feature.Vector(lineString,'',style_green);
vectorLayer.addFeatures([lineFeature]);
map.setCenter(lonLat1,zoom);
} //function
However the name in the popup marker is the same for all markers. i.e. the last name pulled from the db. Can anyone please help with this - I have spent 3 full days trying to fix it!
Thanks in advance!
A few comments:
The PHP code you’ve posted is completely irrelevant, since it’s not seen to be used anywhere.
The objects names and Locations aren’t declared anywhere in the code you posted. What do they contain?
In the code quoted below, you’re creating multiple new Feature objects, but you assign them all to the same property (thereby overwriting that property each time). Is that intentional?
//add info into box
for (z in names) {
feature.data.popup = new OpenLayers.Feature(new OpenLayers.LonLat(names[z]).transform(projLonLat,projMercator));
}
Edit:
This does appear to be where it’s going wrong. You should remove the for...z loop, and replace it with the following code:
//add info into box
feature.data.popup = new OpenLayers.Feature(new OpenLayers.LonLat(names[k]).transform(projLonLat,projMercator));
Since in PHP, you’re using the same index ($v) to fill both arrays, it makes sense to use the same index to read them in javascript...
Aside from that, using the for...in loop on Javascript arrays is not considered good practice, for a number of reasons. It’s better to use the following:
for (k = 0; k < Locations.length; k += 1) {
// your code
}
i had the same problem , and i solve it ...
the problem is overwrite
you don't have to loop inside your function , do the loop for function for example:
function init(z)
{
feature.data.popup = new OpenLayers.Feature(new OpenLayers.LonLat(names[z]).transform(projLonLat,projMercator));
}
for (z in names)
{
init(z)
}