OpenLayers: Zoomable WMS overlay? - maps

I have a problem with WMS overlays in OpenLayers. Basically I just want to add data from a WMS server as an overlay and not as a base layer. This appears to be a very simple problem but I am unable to find a solution. If I set singleTile to true, the overlays appears over the whole map but you cannot zoom in. If it is set to false, only one tile is displayed at every zoom level. If I set it as a base layer, it works just fine but I really want the overlay solution so I can make it transparent and see the map behind it.
Demonstration of the problem, with a different dataset but the issue is the same:
http://jsfiddle.net/adbnC/2/
I think it might be related to some coordinate system issues but I am no expert so any help is appreciated.
Thanks a lot!
Here is the relevant section of the code that does not work as expected:
var pop_layer = new OpenLayers.Layer.WMS("Population Density in 2000",
"http://sedac.ciesin.columbia.edu/geoserver/ows", {
layers: 'gpw-v3:gpw-v3-population-density_2000',
transparent: true
}, {
opacity: 0.5,
isBaseLayer: false,
// Setting single tile to true will kind of work but than one
// cannot zoom in any more.
singleTile: false
}
);

I can't quite get what exactly is wrong here, but I think it has something to do with messed up reference systems. Here is a workaround:
Modified Jsfiddle.net
I changed the map projection to spherical mercator and now it seems to work fine for me:
var mapOptions = {
div: "map",
projection: new OpenLayers.Projection("EPSG:900913"),
units: "m"
};
map = new OpenLayers.Map('map', mapOptions);
var osm = new OpenLayers.Layer.OSM();
map.addLayer(osm);
var pop_layer = new OpenLayers.Layer.WMS("Population Density in 2000", "http://sedac.ciesin.columbia.edu/geoserver/ows", {
layers: 'gpw-v3:gpw-v3-population-density_2000',
transparent: true
}, {
opacity: 0.5,
isBaseLayer: false
});
map.addLayer(osm);
map.addLayer(pop_layer);
map.addControl(new OpenLayers.Control.LayerSwitcher());
map.setCenter(new OpenLayers.LonLat(0, 0), 2);​
Let me know if that helped!

Related

Building timeline for video editor using React JS

Especially looking for an idea or way around to achieve this.
I am trying to build a video editor/mixture as in the above image using react js. This UI primarily targets to align different video/image media with timelines. As user drag video/image in any of the layer, it just needs to expand or shrink with time scale.
Three screens are for three different videos. A feature like a crop/split is not required. This UI collect information and send it to the server which will do the rest of the processing. Required contents are already on our servers.
Any solution/possible direction on collecting media information drag into layers with the time scale on the top ?. What are the best resources to achieve this UI using React JS?
You should be using timeline of vis.js with the following options :
var start = new Date(1970, 0, 1, 0, 0, 0, 0);
var end = new Date(1970, 00, 01, 0, 1, 0, 0);
var options = {
zoomKey: "ctrlKey",
horizontalScroll: true,
verticalScroll: true,
orientation: "top",
moveable: true,
zoomable : true,
editable: true,
min: start,
max: end,
start: start,
end: end,
zoomMax: 10000000,
zoomMin: 1000,
stack:false,
showCurrentTime: true,
multiselect: true,
multiselectPerGroup: true,
};
This will give you a multiline scrollable (both horizontal and vertical) sliding timeline which is the basis of a video editor.
I suggest your timeLine component to have a module and scale both provided by its father component. The nested divs have their own module length, but not scale, and the same happens with the timeLine component. So, you only talk about modules length. Then i.e. you set the equivalence 1 module = 50px
I hope this help you!

Rare effect when toggling BaseLayer in leaflet with react-leaflet

My application shows a map with react-leaflet and uses LayersControl to switch between an OSM TileLayer and HERE TileLayer. The code is as follows:
<LayersControl position="topright">
<LayersControl.BaseLayer
name={this.props.intl.formatMessage({id:'map.normal_map'})}
checked={true}
>
{ tileLayerOSM }
</LayersControl.BaseLayer>
<LayersControl.BaseLayer name={this.props.intl.formatMessage({id:'map.terrain_map'})}>
{ tileLayerHERE }
</LayersControl.BaseLayer>
</LayersControl>
The problema I see is the following: when moving the OSM map, some 'squares' are downloaded from HERE while they are not ready with OSM. See the network trace:
I would like to avoid this behavior, since it is a bit annoying for the user, who see changes in the visualization for a short period of time.
I don't have experience using Leaflet with React, but these is clearly not the desired behaviour.
In Leaflet that (retrive the both base layers at the same time) happens when you add both to the map. Something like:
const accessToken = 'foo';
let osm = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
const mapbox = 'https://api.mapbox.com/styles/v1/mapbox/basic-9/tiles/256/{z}/{x}/{y}?access_token={accessToken}';
const map = L.map('map').setView([42.2, -8.8], 12);
map.addLayer(osm);
map.addLayer(mapbox); // only one should be added to the map
or directly when instantiating the map:
let map = L.map('map', {
center: [42.2, -8.8],
zoom: 12,
layers: [osm, mapbox] // only one should be added to the map
});
With this kind of baselayers you only must add one to the map and use the layer control to switch between one or the other. When only one is added only the tiles for one of the maps are requested, saving bandwith.
As a "shot in the dark" I will try to make the checked value explicit for all layers. First both as a harcoded false, nothing should be shown in the map. Then one with checked=true harcoded and the other with false, and so on. Probably the trouble is how those attributes are managed.

how to update google chart?

Am new to angularjs/googlecharts and learning on the job. I've the following code in my controller which renders the piechart initially and has no issues.
There is a slider directive, which when changed (basically a date range slider), should update the columnchart with new data. But I don't know how to update the piechart data. I do get the new data from the backend without any problems though.
Here is the initialization code in controller:
$scope.piechart = {};
$scope.piechart.type ='PieChart';
piechartData = response.data.piechart;
var piechartoptions = {
'min-width':800,
'max-width':320,
'is3D':true,
'pieSliceText': 'label',
'pieSliceTextStyle': {fontSize: 10},
'chartArea' : { left: 30, top: 60 },
'backgroundColor': {fill:'transparent'},
'legend': {'textStyle':{'color': 'white',
'fontSize': 12},
'position': "top",
'maxLines':10,
'alignment':"start"},
'height':500
};
$scope.piechart.data = new google.visualization.DataTable(piechartData);
$scope.piechart.options = piechartoptions;
$scope.piechart.formatters = {};
In the directive (which is used in the html that the above controller's scope resides in), I've access to the chart like the following:
scope.$parent.piechart
So in a very naive way i did this but to no avail:
scope.$parent.piechart.data = new google.visualization.DataTable(response.data.piechart)
TIA for all the help.
I bumped into this issue today. An easy quick fix is to simply write
this.chartData = Object.assign([], this.chartData) to reassign to the exposed dataset property into your component so it triggers change detection.
More information from this issue in a different library:
valor-software/ng2-charts#959 (comment)
Hope this helps weary travellers :)
To achieve this you need to create watch on your slider model so when it gets change you need to update your pie chart model so it'll automatically update.
Watch
$scope.$watch('sliderModel',function(n,o) {
// update your new pie chart data here, I think you need to update below model only
$scope.piechart.data = new google.visualization.DataTable(piechartData);
}
It just an example. You have to update it with new data for pie chart.
Proper Angular way to use google chart
You should use google-chart directives to plot pie chart so this kind of problems will be solved automatically.
Have a look here - Angular-google-chart

How do I highlight Africa and other regions using the Google Visualization Geochart?

I'm trying to find a map solution that is possible to highlight and click on various regions, one region would be Africa. I'm also looking for a solution that will work well with Angularjs.
I thought the Google Visualization Chart might be suitable. This allows the selection of regions using the region codes listed on the site.
I've tried adding a few regions, the only one I could get working was Australia (AU), the following don't work for me:
['Europe', 150],
['Western Asia', 145],
['Asia', 142],
['Africa', 002]
Here's the jsfiddle I'm using to test this.
Am I doing something wrong or is there an issue with the chart itself?
Thank you.
google.setOnLoadCallback(drawRegionsMap);
function drawRegionsMap() {
var data = google.visualization.arrayToDataTable([
['Region Code', 'Continent', 'Popularity'],
['142', 'Asia', 200],
['150', 'Europe', 300],
['019', 'Americas', 400],
['009', 'Oceania', 600],
['002', 'Africa', 700]
]);
var options = {
resolution: 'continents'
};
var chart = new google.visualization.GeoChart(document.getElementById('regions_div'));
chart.draw(data, options);
}
This jsfiddle shows how to do it:

date of street view static image

I am using Google's Street View Static Image API. It works great, but I am wondering if it is possible to get meta data for the images I am saving, specifically the date. Is there anyway to know the date of the static image?
Thanks,
Lee
Yes, you can get the image date using the Google Maps Street View Service in JavaScript.
Briefly, you would need to go through the usual setup steps to get Google Maps working on your page, then you would do something akin to:
var sv = new google.maps.StreetViewService();
var berkeley = new google.maps.LatLng(37.869085,-122.254775);
sv.getPanoramaByLocation(berkeley, 50, function(data) {
console.log(data.imageDate);
});
data.imageDate will contain the date in YYYY-MM format.
You can use StreetViewService's both getPanoramaById and getPanoramaByLocation methods to obtain this data. Please see here.
var panoramaOptions = {
position: streetViewLocation,
pov: {
heading: 0,
pitch: 5,
zoom: 1
},
visible: true,
addressControl: false,
imageDateControl:true
};

Resources