Using Custom Map Projection On Leaflet - javascript

I have an application displaying a EPSG:3414 map running on Openlayers - jsfiddle working sample that works.
I am trying to implement the same on Leaflet - jsfiddle non-working, it is not working as I may have left out something or may have gotten some concept wrong.
Unfortunately, I am quite unfamiliar and am in the process of figuring out how to get this to work.
Any help would be welcome. Thanks!
Updates:
map is ESRI type using ZYX and SVY21 projection):
updated code here (JS fiddle not updated)
the map X-Y does not start at 0/0, they are some other numbers, so it is getting more complicated, I have to do some magic number offset for each level, this works somewhat but is not ideal as the locations are not accurate, close but not accurate enough.
Leaflet Sample:
var proj = new L.Proj.CRS.TMS('EPSG:3414', "+proj=tmerc +lat_0=1.366666666666667 +lon_0=103.8333333333333 +k=1 +x_0=28001.642 +y_0=38744.572 +ellps=WGS84 +units=m +no_defs",
[4257.9355, 11470.3186, 64359.3062, 49067.5413],
{
resolutions:[76.4372195411057,38.2186097705529,19.1093048852764,9.55465244263822,4.77732622131911,2.38866311065955,1.19433155532978,0.597165777664889,0.298450596901194]
}
);
var map = L.map('my_map', {
crs: proj,
continuousWorld: true,
worldCopyJump: false
});
map.addLayer(new L.Proj.TileLayer.TMS('http://{s}.onemap.sg/ArcGIS/rest/services/basemap/MapServer/tile/{z}/{y}/{x}', proj, {
subdomains: ['t1', 't2'],
tms: true,
continuousWorld: true
}));

Does this example
http://esri.github.io/esri-leaflet/examples/non-mercator-projection.html
or this example help
http://blog.thematicmapping.org/2012/07/using-custom-projections-with-tilecache.html
I would use firebug in firefox with the example and then look to see if there are error messages in the console.
Also I would try it on a straight web page before I put it in JS Fiddle. Just one less thing that might be interfering.

Related

openlayers 6 map getview fit zooms out on every refresh

Im using openlayers 6, on mounted I use map().getView().fit(extent)
for some reason on every refresh the zoom level is higher.
any tips how to fix this?
Before using .fit(extent) I have to transformExtent to change projection from 5514 to 3857
this.map().setView(new View({
projection: 'EPSG:3857',
center: fromLonLat([50.075710, 14.472606]),
zoom: 10,
enableRotation: false
}))
extent = transformExtent(extent, 'EPSG:5514', this.map().getView().getProjection().getCode())
this.map().getView().fit(extent)
before refresh:
after refresh:
my problem is with map.getview.fit
here is my code and here are the returned values
coordinates after view.fit are a bit different
console.log(transformedExtent)
this.map().getView().fit(transformedExtent, this.map().getSize())
console.log(this.map().getView().calculateExtent(this.map().getSize()))
before fit:
-27186.072153485078
6701982.491006854
-5136.804165771885
6724373.669054876
after fit:
-27186.072153485078
6701493.775314425
-5136.804165771886
6724862.384747305
Asked about this problem directly on openlayers github and it is expected behavior.
https://github.com/openlayers/openlayers/issues/13503
You are using the same variable for the EPSG:5514 and EPSG:3857 extents so presumably corrupting the original EPSG:5514 you want to use. Using a separate variable should solve the problem.
const transformedExtent = transformExtent(extent, 'EPSG:5514', this.map().getView().getProjection().getCode())
this.map().getView().fit(transformedExtent)

Streetview Gives blackbox with Navbuttons, no street image, when loading

I'm using react to load streetview into a component I get this :
As we can see - the map component loads fine, and the streetview component seems to load fine, except that the image behind it (the actual street view) isn't loaded.
The error reported is :
**
Uncaught TypeError: Cannot read property 'toString' of undefined in
maps.googleapis.com/imagery_viewer.js:299
**
When I run similar code in straight-up HTML, this works ... sometimes ... often I get no returned image
I've isolated the code into a special function triggered with a large setTimeout() call so that the document load time is not to blame. Indeed, using watches and breakbpoints, we can see that the DIVs are loaded and accessible at run time.
handleLoad: ->
options = {
addressControl: true
fullscreenControl: true
panControl: true
pov: this.props.image.pov
visible: true
zoomControl: true
}
if this.props.image.pano
options.pano = this.props.image.pano
else if this.props.image.position
options.position = new google.maps.LatLng this.props.image.position[0], this.props.image.position[1]
if this.props.image.position
pos = new google.maps.LatLng this.props.image.position[0], this.props.image.position[1]
else
pos = {lat: this.props.entryLatitude, lng: this.props.entryLongitude};
options.key ='XXXX - GOOGLE MAP API KEY GOES HERE - XXXX';
this.map = new google.maps.Map(this.mapDiv, { center: pos, zoom: 14, visible:true } , streetViewControl: false);
this.panorama = new google.maps.StreetViewPanorama this.panoramaDiv, options;
this.map.setStreetView(this.panorama);
Any suggestions what could be causing this problem ?
This known black street view panorama issue can be cache or cors related. I suggest you first try ruling both of them out. E.g. see https://support.google.com/maps/thread/6166296?msgid=8836199
It may also be due to a third-party library bug or conflict. E.g. if you're using mootools or prototype.js check out these threads:
Mootools breaks Google maps streetview - black screen
https://issuetracker.google.com/issues/139252493
Another potential reason could be that your lat/lngs are far away from the roads where the street view imagery is available. Have a look at this great answer to related question Google map JS API "StreetViewPanorama" display black screen for some address
Let us know if any of the linked solutions work for you; otherwise please provide a codesandbox or stackblitz that reproduces the issue and I'll be happy to investigate further.

Finding vector source features in extent with wrapX

I currently have features on an ol.source.Vector that I would like to find by drawing a box (MultiPolygon) on the screen. I currently have this functionality working, however, if I move onto the next rendered world ("spin the globe" so to speak) when I draw my box over the same set of rendered features I get nothing back.
Example code:
var featureSource = new ol.source.Vector({
url: '/ShinyService/feature/geoJson',
format: new ol.format.GeoJSON()
});
var featureLayer = new ol.layer.Vector( {
source: featureSource
});
var myMap = new ol.Map({
layers: [ featureLayer],
view: new ol.View({
minZoom: 3,
maxZoom: 10
});
});
//Later within interaction event (draw end)
var boxExtent = box.getGeometry().getExtent();
vectorSource.forEachFeatureInExtent(boxExtent, function(feature){
foundFeature.push(feature.getId());
});
I'm currently thinking the only "solution" to this is to no longer allow the world to be rendered multiple times, but I don't think this is an option for the requirement I'm trying to fulfill.
I'm currently using Openlayers v3.18.2
Any help would be appreciated!
I was able to figure my problem out. It turned out I had to "wrap" the coordinates of my extent in order to get it to work properly as they were going past the -180 to 180 boundary. Once I did this every thing seemed to work.
However, this feels like something that should already be done in Openlayers so there could be something else I could be missing.

Openlayers initial extent

According to the OpenLayers documentation, the constructor, OpenLayers.Map(), allows for an additional property extent which is "The initial extent of the map" (see here).
However, I cannot get it to have any effect. I know I can set an initial extent by calling .zoomToExtent() after constructing the map. But I would like to use this extent property because I set a zoomend event in the eventListeners property but don't want it to trigger with an initial call to .zoomToExtent(). Does anyone have a clue how to use this extent property?
This is the code that isn't working
map = new OpenLayers.Map('map',{
extent: bounds,
layers: [osmLayer,vectorLayer],
projection: "EPSG:900913",
eventListeners: {
zoomend: function() {
//..zoomend event listener code
}
}
});
In the above example:
bounds is a valid OpenLayers.Bounds object
osmLayer and vectorLayer are valid OpenLayers.Layer objects of which osmLayer is the base layer.
What happens with above code is that the map is completely zoomed out (in fact you can't actually see anything) and any attempts to pan results in errors being thrown. To get to map into a correct state the user has to zoom in and then panning works again and you can see the map.
I'm afraid I'm not sure off-handedly how to make the code you listed work, however the following alternative has worked for me:
map = new OpenLayers.Map('map',{projection: new OpenLayers.Projection("EPSG:4326")});
//ADD A BUNCH OF LAYERS AND SUCH HERE
//Set map center to this location at this zoom level
map.setCenter(new OpenLayers.LonLat(-93.9196,45.7326),5);
As a last resort, you could put a line at the beginning of your zoom function:
if(!map_ready) return;
And then set the variable map_ready to true at the appropriate time.
I ran into the same problem.
The "extent" option mentioned in the documentation is there probably by mistake. It does not exist. I checked the source code and could not see any code handling such option. I contacted the author and he already created a pull request for the removal of this option from the documentation.

OpenLayers Refresh Strategy Problems

I'm developing an application, part of which uses OpenLayers (calling a Geoserver-served WMS) displaying some frequently updated data (a vessel track - or more specifically, a series of points).
I would like to have this vessel track updated at a set interval - OpenLayers.Strategy.Refresh seems like the most approparite way to do this. I modified the wms.html example (OpenLayers 2.11) slightly to try this, ie:
underway = new OpenLayers.Layer.WMS("Underway Data",
"http://ubuntu-geospatial-server:8080/geoserver/underway/wms",
{'layers': 'underway:ss2011_v03', transparent: true, format: 'image/gif'},
{isBaseLayer: false},
{strategies : [new OpenLayers.Strategy.Refresh({interval: 6000})]}
);
map.addLayers([layer, underway]);
From what I can tell, this should work as-is (ie refresh the underway layer every 6 seconds), however nothing happens. The underlying WMS is getting updated - if I refresh the map manually, the updated data will appear.
I'm sure I'm missing something fairly obvious, any help would be much appreciated. I'm not getting any errors in Firebug or anything, it's just not doing anything.
Well, it turns out that you can't do a refresh strategy on a WMS service, as far as I can tell. So I converted my code to use WFS instead, and it works as expected. The code:
underway = new OpenLayers.Layer.Vector("WFS", {
strategies: [new OpenLayers.Strategy.BBOX(), new OpenLayers.Strategy.Refresh({interval: 4000, force: true})],
protocol: new OpenLayers.Protocol.WFS({
url: "http://ubuntu-geospatial-server:8080/geoserver/wfs",
featureType: "ss2011_v03",
featureNS: "http://csiro.au/underway",
geometryName: "position"
});
Note that I also need a BBOX strategy. Another gotcha that I found was that I needed to manually specify the geometryName, otherwise it would default to "the_geom", which doesn't exist for my layer.
I'm pretty sure you need to add a new OpenLayers.Strategy.Static() strategy for it to work.
And you need to activate your Refresh strategy which means you have to stick it in a separate variable.

Categories