OpenLayers request tiles out of range - maps

OpenLayers map is requesting tiles out of range and all the map is pink.
If I inspect single tile, the address is next:
/Tiles/15/16384/16384.png
But the folder with generated tiles does not contain such values:
The range is only: /Tiles/15/16099 - /Tiles/15/16119
The tiles are generated by Maperitive.
Is it a Maperitive problem or I should set additional options to OpenLayers.Map?
map = new OpenLayers.Map("demoMap");
var cLayer2 = new OpenLayers.Layer.OSM("New Layer",
"http://localhost:15157/Map/Tiles/${z}/${x}/${y}.png", { numZoomLevels: 19 });
map.addLayer(cLayer2);
map.zoomToMaxExtent();

Related

ARKit - ARRreferenceImage tracking

I'm playing around with ARReferenceImages in ARKit and I'm trying to add an SCNNode when a reference image is recognised and then leave that node in place regardless of whether the same reference image is then recognised elsewhere.
I can add my SCNode correctly, but if I move my marker it picks it up again and moves my placed node to the position of the marker.
My code to add is as follows:
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
guard let imageAnchor = anchor as? ARImageAnchor else { return }
let referenceImage = imageAnchor.referenceImage
print("MAPNODE IS NIL = \(self.mapNode == nil)")
updateQueue.async {
if self.mapNode == nil {
// Create a plane to visualize the initial position of the detected image.
let plane = SCNPlane(width: 1.2912,
height: 1.2912)
let planeNode = SCNNode(geometry: plane)
planeNode.opacity = 1
/*
`SCNPlane` is vertically oriented in its local coordinate space, but
`ARImageAnchor` assumes the image is horizontal in its local space, so
rotate the plane to match.
*/
planeNode.eulerAngles.x = -.pi / 2
self.mapNode = planeNode
/*
Image anchors are not tracked after initial detection, so create an
animation that limits the duration for which the plane visualization appears.
*/
// Add the plane visualization to the scene.
node.addChildNode(planeNode)
}
}
}
reading the docs here https://developer.apple.com/documentation/arkit/recognizing_images_in_an_ar_experience#2958517 it states that
Apply Best Practices
This example app simply visualizes where ARKit detects each reference
image in the user’s environment, but your app can do much more. Follow
the tips below to design AR experiences that use image detection well.
Use detected images to set a frame of reference for the AR scene.
Instead of requiring the user to choose a place for virtual content,
or arbitrarily placing content in the user’s environment, use detected
images to anchor the virtual scene. You can even use multiple detected
images. For example, an app for a retail store could make a virtual
character appear to emerge from a store’s front door by recognizing
posters placed on either side of the door and then calculating a
position for the character directly between the posters.
Note
Use the ARSession setWorldOrigin(relativeTransform:) method to
redefine the world coordinate system so that you can place all anchors
and other content relative to the reference point you choose.
Design your AR experience to use detected images as a starting point
for virtual content. ARKit doesn’t track changes to the position or
orientation of each detected image. If you try to place virtual
content that stays attached to a detected image, that content may not
appear to stay in place correctly. Instead, use detected images as a
frame of reference for starting a dynamic scene. For example, your app
might recognize theater posters for a sci-fi film and then have
virtual spaceships appear to emerge from the posters and fly around
the environment.
So I tried setting my world transform to be equal to the transform of my image anchor
self.session.setWorldOrigin(relativeTransform: imageAnchor.transform)
However my mapNode follows the imageAnchor where ever it moves. I haven't implemented the renderer update method so I'm not sure why this keeps moving.
I'm assuming that the setWorldOrigin method is constantly updating to the imageAnchor.transform and not just that moment in time, which is weird as that code is only called once. Any ideas?
If you want to add the mapNode at the position of the ARImageAnchor you could set the position of your mapNode at the transform of the ARImageAnchor and add it to the scene but not linked to the reference image if that makes sense.
This could be done like so:
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
//1. If Out Target Image Has Been Detected Than Get The Corresponding Anchor
guard let currentImageAnchor = anchor as? ARImageAnchor else { return }
//2. An ImageAnchor Is Only Added Once For Each Identified Target
print("Anchor ID = \(currentImageAnchor.identifier)")
//3. Add An SCNNode At The Position Of The Identified ImageTarget
let nodeHolder = SCNNode()
let nodeGeometry = SCNBox(width: 0.02, height: 0.02, length: 0.02, chamferRadius: 0)
nodeGeometry.firstMaterial?.diffuse.contents = UIColor.cyan
nodeHolder.geometry = nodeGeometry
nodeHolder.position = SCNVector3(currentImageAnchor.transform.columns.3.x,
currentImageAnchor.transform.columns.3.y,
currentImageAnchor.transform.columns.3.z)
augmentedRealityView?.scene.rootNode.addChildNode(nodeHolder)
}
In another part of your question you seem to imply that you want to detect multiple occurrences of the same image. I could be wrong but I think the only way to do this is to remove the corresponding ARImageAnchor for the reference image, which can be done like so (by adding it at the end of the last code snippet):
augmentedRealitySession.remove(anchor: currentImageAnchor)
The issue here is that once the ARImageAnchor is removed, any time it is detected again, you would have to handle whether content should be added, which is tricky since the ARImageAnchor.identifier is always the same for the referenceImage regardless of whether it is removed and then re-added thus making it difficult to store in a dictionary etc. As such depending on your needs you would then need to find a way to determine if content existed at that location and whether to re add it etc.
The last part of your question about setWorldOrigin seems a bit odd like you said, but maybe you could add a Bool to prevent it from potentially changing e.g:
var hasSetWorldOrigin = false
Then based on this you could ensure that it is only set once e.g:
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
//1. If Out Target Image Has Been Detected Than Get The Corresponding Anchor
guard let currentImageAnchor = anchor as? ARImageAnchor else { return }
//2. If We Havent Set The World Origin Set It Based On The ImageAnchorTranform
if !hasSetWorldOrigin{
self.augmentedRealitySession.setWorldOrigin(relativeTransform: currentImageAnchor.transform)
hasSetWorldOrigin = true
//3. Create Two Nodes To Add To The Scene And Distribute Them
let nodeHolderA = SCNNode()
let nodeGeometryA = SCNBox(width: 0.04, height: 0.04, length: 0.04, chamferRadius: 0)
nodeGeometryA.firstMaterial?.diffuse.contents = UIColor.green
nodeHolderA.geometry = nodeGeometryA
let nodeHolderB = SCNNode()
let nodeGeometryB = SCNBox(width: 0.04, height: 0.04, length: 0.04, chamferRadius: 0)
nodeGeometryB.firstMaterial?.diffuse.contents = UIColor.red
nodeHolderB.geometry = nodeGeometryB
if let cameraTransform = augmentedRealitySession.currentFrame?.camera.transform{
nodeHolderA.simdPosition = float3(cameraTransform.columns.3.x,
cameraTransform.columns.3.y,
cameraTransform.columns.3.z)
nodeHolderB.simdPosition = float3(cameraTransform.columns.3.x + 0.2,
cameraTransform.columns.3.y,
cameraTransform.columns.3.z)
}
augmentedRealityView?.scene.rootNode.addChildNode(nodeHolderA)
augmentedRealityView?.scene.rootNode.addChildNode(nodeHolderB)
}
}
Hopefully my answer will provide a useful starting point to you assuming of course I have interpreted your question correctly,

add result of image.plot layer on geographic map (bing map)

I have a 2D footprint result for an eddy-covariance system on a 1100*1100 square meter, with the domain of
domain = c(-100,1000,-100, 1000)
the cell size of the domain (each grid) is 2 meters with the origin (0,0) accordingly on this location:
Lon = -97.191391 #longtitude
Lat = 36.055935 #latitude
An example data (9.01 Mb) is attached here. FFP.rds
then I can plot a Bing map on my site as this:
library(OpenStreetMap)
library(rgdal)
map <- openmap(c(36.05778,-97.19250), c(36.05444,-97.18861),type='bing')
plot(map)
and I use image.plot() from package "fields" to plot the footprint with these following codes:
library(fields)
str(FFP$fclim_2d)
image.plot(FFP$x_2d[1,],FFP$y_2d[,1],FFP$fclim_2d)
But I am wondering how to scale each grid of my footprint result to Bing map (or google map).
Any suggestions would be greatly appreciated.

How to control/scale image size in Codename One?

I used the (new) GUI Builder and inserted an image (by way of adding a Label). However, it appears too big. Is there anyway I can scale and control the size? (I saw something which points to cloudinary but that seems too complicated. I just want to simply scale down the image.)
There are several ways to resize images in Codename One and I will mention few below:
1.
Use MultiImages in the GUI Builder. With this multiple sizes of images are generated from one image based on the sizes you specified. In your GUI Builder, Click Images -> Add Multi Images -> Select your image -> Check Preserve Aspect Ratio -> Increase the % that represents the percentage of the screen width you want the image to occupy. Set any DPI you don't require to 0.
2.
Use ScaledImageLabel or ScaledImageButton, it will resize the image the fill available space the component is occupying.
3.
Scale the image itself in code (This is not efficient, though):
public static Image getImageFromTheme(String name) {
try {
Resources resFile = Resources.openLayered("/theme");
Image image = resFile.getImage(name);
return image;
} catch (IOException ioe) {
//Log.p("Image " + name + " not found: " + ioe);
}
return null;
}
Image resizedImage = getImageFromTheme("myImage").scaledWidth(Math.round(Display.getInstance().getDisplayWidth() / 10)); //change value as necessary
4.
Mutate the image (Create an image from another image).

Scale radius of circle based on range of string - Mapbox

I'm trying to dynamically set the radius of circles plotted with a dataset that has three columns: Latitude / Longitude / # of Sessions. Data imports fine and all the locations plot correctly with the # of sessions as the label.
Here's the scenario:
The radius should be based on the number of sessions, so a lat/lon pair with 5 sessions is 1px, a lat/long pair with 5,000 sessions is 10px, etc.
Is there a way to have this dynamically set in a dataset? I can create layer "bands" myself by adding multiple instances of the dataset and filtering to 1-10, 11-100, etc., but it'd be great to set a "min" radius and a "max" radius and have it auto-scale based on available data.
Is there a way to do this in Mapbox?
Assuming I understand this right - basically you have some type of data based off of the session # you'd like to draw a bigger or smaller circle on that lat, long pairing.
What you can do is originally import the data followed by taking the # of sessions and physically creating a set to render on the map (some type of array or something). You can use mapbox markers to render these icons or circle and physically assign them a size.
Prior to this you will have to pre-determine a function to take the # of sessions and map them to a physical radius value - say 1000 sessions = a radius of 10 and 50,000 sessions = a radius of 500.
For example in an ios app I created this is my code, using - https://github.com/mapbox/react-native-mapbox-gl
markersArray = markersArray.concat({
coordinates:[bList[i].latitude, bList[i].longitude],
'type': 'point',
title: bList[i].bname,
subtitle: bList[i].data,
id: bList[i].o_ID.toString(),
startTime: bList[i].startTime,
endTime: bList[i].endTime,
annotationImage: {
url: (bList[i].type === 'drink') ? (drinkUrl) : (foodUrl),
height: 30,
width: 30
},
rightCalloutAccessory: {
url: 'image!info-icon',
height: 20,
width: 20
}
});

Using custom map image tiles in LeafletJS?

Do my tiles need to adhere to any particular specs?
I have a large image file which I'd like to turn into a map with LeafletJS. I am going to be using the Python Imaging Library to cut it up into all the various tiles I need.
However, I can't find any information about using custom maps in Leaflet. Do I provide Leaflet with the range of X,Y,Z info somehow? Do I give it the pixel size of each tile? Does it figure this out on its own?
To put my question into one concise question: What do I need to do in order to have image files that can double as map tiles with LeafletJS, and what, if anything, do I need to do in my front-end script? (beyond the obvious specifying of my custom URL)
You are looking for a TileLayer. In this TileLayer, you give the URL for the to-be-fetched images to leaflet with a template like this:
http://{s}.somedomain.com/blabla/{z}/{x}/{y}.png
When you are at the specified zoom, x and y level, Leaflet will automatically fetch the tiles on the URL you gave.
Depending on the image you want to show, the bigger part of the work will however be in the tile generation. Tiles by default have a 256x256px size (can be changed in the TileLayer options), and if you are using geodata the used projection is Mercator projection. It may take some time to get the tile ids right. Here is an example on how the tile ids work.
You can even serve tiles directly from a database.
The format leaflet specifies is very flexible.
Leaflet just uses the z,x,y place holders to request specific tiles.
For example:
L.tileLayer('http://localhost/tileserver/tile.aspx?z={z}&x={x}&y={y}', {
minZoom: 7, maxZoom: 16,
attribution: 'My Tile Server'
}).addTo(map);
where Tiles.aspx
Option Strict On
Partial Class tile
Inherits System.Web.UI.Page
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim z, x, y As Integer
z = CInt(Request.QueryString("z"))
x = CInt(Request.QueryString("x"))
y = CInt(Request.QueryString("y"))
Dim b() As Byte = DB.GetTile(z, x, y)
Response.Buffer = True
Response.Charset = ""
'Response.Cache.SetCacheability(HttpCacheability.NoCache)
Response.ContentType = "image/png"
Response.AddHeader("content-disposition", "attachment;filename=" & y & ".png")
Response.BinaryWrite(b)
Response.Flush()
Response.End()
End Sub

Resources