OpenLayers 3: per-layer translation for tiled image layers - openlayers-3

Sometimes it's useful to apply translation (that is, pixel offset) to a layer (and not other layers).
For example, two line-based layers can be visually compared by translating (that is, offsetting) a layer.
For vector layers, it can be done by translating vector features. But for the tiled image layers, (for example, road traffic information tiles generated by GeoServer) how can it be done?

This is also a nice example for precompose and postcompose render event handlers.
precompose is triggered before a layer is rendered, and postcompose afterwards. Inside the event handlers you have direct access to the canvas context, so you can use CanvasRenderingContext2D.translate() to offset the rendering for a layer.
roads2.on('precompose', function(event) {
var ctx = event.context;
ctx.save();
ctx.translate(10, 10);
});
roads2.on('postcompose', function(event) {
var ctx = event.context;
ctx.restore();
});
http://jsfiddle.net/m1abjrkm/3/
Note: This example does not take into account rotated maps!
Update: As #zeodtr points out in his comment, there is a problem at the tile borders with this approach. The following screenshot created by him illustrates the problem:

Related

how draw foreground in flame_tiled

I need help to draw map created from Tiled (.tmx)
version info
flame: 1.5.0
flame_tiled: 1.9.0
what I want is to draw background first, then player, then foreground.
I have 4 layer for now,
foreground (tile layer) (top layer).
spawn (object layer).
housing (tile layer).
land (tile layer).
already working with drawing background and player and foreground with this code. but I need to save 2 file of map data.
final currentMap = await TiledComponent.load(
'$mapName.tmx',
Vector2.all(16),
);
add(currentMap);
final spawnPointObject = currentMap.tileMap.getLayer<ObjectGroup>('spawn');
for (final spawnPoint in spawnPointObject!.objects) {
final positions = Vector2(
spawnPoint.x + (spawnPoint.width / 2),
spawnPoint.y + (spawnPoint.height / 2),
);
switch (spawnPoint.class_) {
case 'player':
_player = MyPlayer(
anchor: Anchor.center,
current: 'idle',
position: positions,
size: Vector2.all(16),
name: name,
);
add(_player);
break;
}
}
final currentForeground = await TiledComponent.load(
'${mapName}_foreground.tmx',
Vector2.all(16),
);
add(currentForeground);
I can draw from object layer, but take soo much case will be hard for update later..
so is there any way to draw only 1 layer with flame_tiled.?
this is sample image, I want my player to draw behing the roof when played.
image
- already try with layer object and drawing base on object id, one by one. but take so much effort.
- try with 2 save file, but still hard to maintain (used now)
My personal conclusion about this problem is that flame_tiled is not flexible enough, so the best thing it can do for you is to parse map files. If you need a flexible rendering, you going to implement it on your side, because flame_tiled renders everything as a big flat batch of sprites.
Probably you can do a fast hack by rendering the RenderableTiledMap twice. At first pass you disable "roof" map's layers (see "setLayerVisibility" function) and renders everything into a Picture / Image and wraps it into a component with "ground" priority.
Than you enable "roof" layer and disable "ground", then do the same rendering into another Picture / Image and wraps it into another component with "roof" priority.
Trying to solve this problem, I have made two solutions. One is simpler, another is more complicated and still in development / debug stage:
https://pub.dev/packages/flame_tiled_utils - with this you can render every map's tile as a component into separate layer with given priority. Exactly what you want, but you need to create some additional classes to describe your map's tile types.
https://github.com/ASGAlex/flame_spatial_grid - allows to do the same, but with better abstraction level. Also helps to avoid problems of the previous library (slow rendering on large maps). But it is still in heavy development, sometimes I broke something, sometimes fix...
Sorry for such "longread" answer =)

OL3:How to judge a point feature in a specific vector source?

In my website builded with ol3, I have two or more vector layers with different sources in my map, i want to click features in a specific source and show some popup. My way is adding a single click event on my map, and using source.getFeaturesAtCoordinate(evt.coordinate) but always get empty results [].What can i do in this situation?
For points, you would need to be extremely lucky to hit the exact coordinate. You need to consider the rendered size of your points, and for that you'd better use ol.Map#forEachFeatureAtPixel(). It works on the layer, not the source:
map.forEachFeatureAtPixel(evt.pixel, function(feature, layer) {
// get the source
source = layer.getSource();
// do something with the feature
});

OpenLayers 3 : put one layer in grayscale without changing other layers

I have a tricky question concerning the possibility to put layers in grayscale with Open Layers 3.
I already achieve to put the whole map in grayscale using the possibilities of canvas element, like it can be seen in the examples proposed in the following discussion : OpenLayers 3 - tile canvas context
But my need is slightly different from these examples : I want to give users the possibility to put layers one by one in grayscale, without changing the colour of other layers. The idea is for instance to have one background layer in grayscale with other data over it in colour.
Does someone know how such a thing can be achieved ?
Thanks
ol.source.Raster is what you are looking for. Here is an example.
var raster = new ol.source.Raster({
sources: [new ol.source.Stamen({
layer: 'watercolor'
})],
operation: function(pixels, data) {
// convert pixels to grayscale
return pixels;
}
});
This enables you to manipulate the pixel data of arbitrary sources on a per-layer base.

Disable interim tiles for tile layer

When creating a map like this:
var map = new ol.Map({
loadTilesWhileAnimating: true,
loadTilesWhileInteracting: true
})
OpenLayers 3 uses interim tiles (i.e., previously loaded lower resolution tiles) when zooming and panning until it has finished loading the new tiles.
The interim tiles are placed behind the real tiles. Which is very clever, and is great for opaque layers, but much not so great for mostly transparent layers.
We currently have a layer which consists of just a few lines, only a few pixels think. Slightly panning the map makes these into huge blobs, causes a lot of flicker.
Is there a way to disable creating of these interim tiles, just for a specific layer? It would be disappointing if I'd need to disable both loadTilesWhile* properties just because of a single layer.
For an example, see: http://imgur.com/RbtmkpT
The left is normal (the red line is mine), right is after panning slightly.
This is with cacheSize 0 on the source and useInterimTilesOnError false.
Update:
OpenLayers 3.12 behaves differently. In that version, only unloaded tiles are blurry (which is to be expected), but already loaded tiles are left alone. Starting from 3.13 or 3.14, this behavior changed.
See my pull request in the OpenLayers GitHub repository for a solution / workaround:
https://github.com/openlayers/ol3/issues/5251#issuecomment-212322292

Dynamically alter or destroy a Texture2D for drawing and collision detection

I am using XNA for a 2D project. I have a problem and I don't know which way to solve it. I have a texture (an image) that is drawn to the screen for example:
|+++|+++|
|---|---|
|+++|+++|
Now I want to be able to destroy part of that structure/image so that it looks like:
|+++|
|---|---|
|+++|+++|
so that collision now will work as well for the new image.
Which way would be better to solve this problem:
Swap the whole texture with another texture, that is transparent in the places where it is destroyed.
Use some trickery with spriteBatch.Draw(sourceRectangle, destinationRectangle) to get the desired rectangles drawn, and also do collision checking with this somehow.
Split the texture into 4 smaller textures each of which will be responsible for it's own drawing/collision detection.
Use some other smart-ass way I don't know about.
Any help would be appreciated. Let me know if you need more clarification/examples.
EDIT: To clarify I'll provide an example of usage for this.
Imagine a 4x4 piece of wall that when shot at, a little 1x1 part of it is destroyed.
I'll take the third option:
3 - Split the texture into 4 smaller
textures each of which will be
responsible for it's own
drawing/collision detection.
It's not hard do to. Basically it's just the same of TileSet struct. However, you'll need to change your code to fit this approach.
Read a little about Tiles on: http://www-cs-students.stanford.edu/~amitp/gameprog.html#tiles
Many sites and book said about Tiles and how to use it to build game worlds. But you can use this logic to everything which the whole is compost from little parts.
Let me quick note the other options:
1 - Swap the whole texture with
another texture, that is transparent
in the places where it is destroyed.
No.. have a different image to every different position is bad. If you need to change de texture? Will you remake every image again?
2- Use some trickery with
spriteBatch.Draw(sourceRectangle,
destinationRectangle) to get the
desired rectangles drawn, and also do
collision checking with this somehow.
Unfortunately it's don't work because spriteBatch.Draw only works with Rectangles :(
4 Use some other smart-ass way I don't
know about.
I can't imagine any magic to this. Maybe, you can use another image to make masks. But it's extremely processing-expensive.
Check out this article at Ziggyware. It is about Deformable Terrain, and might be what you are looking for. Essentially, the technique involves settings the pixels you want to hide to transparent.
Option #3 will work.
A more robust system (if you don't want to be limited to boxes) would use per-pixel collision detection. The process basically works as follows:
Calculate a bounding box (or circle) for each object
Check to see if two objects overlap
For each overlap, blit the sprites onto a hidden surface, comparing pixel values as you go. If a pixel is already set when you try to draw the pixel from the second sprite, you have a collision.
Here's a good XNA example (another Ziggyware article, actually): 2D Per Pixel Collision Detection
Some more links:
Can someone explain per-pixel collision detection
XNA 2-d per-pixel collision
I ended up choosing option 3.
Basically I have a Tile class that contains a texture and dimention. Dimention n means that there are n*n subtiles within that tile. I also have an array that keeps track of which tiles are destroyed or not. My class looks like this in pseudo code:
class Tile
texture
dimention
int [,] subtiles; //0 or 1 for each subtile
public Tile() // constructor
subtiles = new int[dimention, dimention];
intialize_subtiles_to(1);
public Draw() // this is how we know which one to draw
//iterate over subtiles
for(int i..
for(int j ...)
if(subtiles[i,j] == 1)
Vector2 draw_pos = Vector2(i*tilewidth,
j*tileheight)
spritebatch.Draw(texture, draw_pos)
In a similar fashion I have a collision method that will check for collision:
public bool collides(Rectangle rect)
//iterate over subtiles
for i...
for j..
if(subtiles[i,j]==0) continue;
subtile_rect = //figure out the rect for this subtile
if(subtile_rect.intersects(rect))
return true;
return false;
And so on. You can imagine how to "destroy" certain subtiles by setting their respective value to 0, and how to check if the whole tile is destroyed.
Granted with this technique, the subtiles will all have the same texture. So far I can't think of a simpler solution.

Resources