How to redraw vector tiles without cleaning cache? - leaflet

I have vector tiles layer, and i want to redraw this layer, but i want to save my cached data.
So i can't use leaflet function redraw() because this is deleting me my cache.
Is there any function to do this? I only want do draw this tiles again without any calculations, because they are made earlier.

So i found an answer. It's probably good.
if our vector tiles layer is called tileLayer, then we can simple write this:
tileLayer._reset();
tileLayer._update();

Related

Flutter - How to move and zoom Canvas drawings without AGAIN running something like the CustomPainter paint method?

I have tried using the methods "Transform.scale" (for "zooming" ) and "Transform.translate" (for the moving), but they seem to trigger the paint method in the CustomPainter.
(even though the method "shouldRepaint" returns false, but that method is not even invoked)
Maybe there is some other way of doing what I want i.e. be able to move and zoom something I have created with a Canvas (without again executing the paint method)?
In the below example code there are three sliders, one for zooming out (i.e. reducing the size) and one for moving horizontally and one for moving vertically.
The "paint" method simply draws a polygon (see the below attached screenshot picture).
While the example code below is simple (i.e. small amount of hardcoded vector data and fast to render), I want to emphasize that the solution I am looking for need to support MANY complicated drawings (with LOTS OF data, slow to render), i.e. it is not an acceptable solution to suggest something like instead manually converting this one vector image to a raster image (e.g. PNG/JPG/GIF).
Below I try do describe how you can think regarding a scenario that need to be supported:
Imagine you want to implement an app with a huge dropdown list with lots of different vector data images to be selected.
The data of those VECTOR images may be retrieved from the internet or from a big local SQLite database.
IMPORTANT: The DATA in those images are NOT raster images such as jpg, png, gif... but the VECTOR data to become retrieved is defined as lots of screen coordinates for points, lines, polygons, and textual labels, and icons, and color values... and so on.
Such VECTOR data will then be used for creating the image, and as far as I understand you should use CustomPainter with the paint method unless there are better options?
Also imagine that each of such selected image with vector data is HUGE with MANY THOUSANDS of lines, polygons, icons, ... and so on, and that the paint method might take seconds for creating the image.
BUT, once it is drawn the data will not change.
So, since the "paint" method might take seconds to render a huge amount of vector data, you want to avoid invoking it frequently, when moving or zooming.
Therefore I think it would be desirable if it would be possible to use the method "shouldRepaint" to return false, but it seems as that method is not even invoked at all when resizing or moving with the Transform methods "scale" and "translate".
But maybe there is some other solution to support the above described scenario, maybe some other class than CustomPainter that do not automatically trigger the paint method when applying Transform scale/translate ?
I hope there is a solution with the Flutter framework somehow being able to automatically reuse the bitmap (e.g color values at certain bits and bytes) that was created potentially slowly with a paint method but can scale/zoom and move it in a faster way than having to execute the paint method again.
If you just want to zoom, scale, pan on your images, then you can try the new InteractiveViewer widget.
InteractiveViewer class
A widget that enables pan and zoom
interactions with its child.
The user can transform the child by dragging to pan or pinching to
zoom.
https://api.flutter.dev/flutter/widgets/InteractiveViewer-class.html

Leaflet: How to use CRS.Simple with TileLayer?

I have a 2048x4096 tiled map with 256x256 tiles.
In Leaflet with a Tilelayer and CRS.Simple, it shows up as about 120x230 pixels instead of the 2048x4096 I expected.
What's going on and how do I control this?
If I examine my map closely, it actually ends up as 128x256 pixels.
I think what's happening is that CRS.Simple, probably inadvertently, scales a tiled map down to fit within one tile.
As it happens, that works quite well for my purpose, so I don't need to pursue this any further.

Vector layers with mapboxgl with no coordinates

Is there a way to draw a vector layer with CorelDraw for example and place it on napboxgl and use it as geojson layers?
For example https://seatgeek.com/colorado-rapids-at-seattle-sounders-fc-tickets/mls/2017-10-22-1-pm/3700786
Are they using geojson or etc.? Or just some sort of vector format?
I can't use geojson as it is hard to draw with QGIS any straight lines or symmetrical objects. I just want to draw a lot of vector objects and use them as layers with mapboxGL(use mapbox as render method and interact with layers as with geojson)
Any suggestions how to do it? Or is there a way to draw with Corel and then place it on map with QGIS?
Thanks
UPD:
Now I am using Corel -> dxf export and then import it to QGIS, then save it as geojson. But have some glitches with displaying that geojson geometry in mapbox, so I have to draw another in QGIS over the imported(dxf) one.
Here is an example of the bug, should be just a green polygon like the gray one
UPDATE: my fault, I was using lines instead of polygons.
I think you can achieve this as follows:
Convert the Corel output to SVG
Create an HTML element containing the SVG (not necessarily added to DOM)
On your Mapbox map, add a Canvas source containing the canvas: see https://www.mapbox.com/mapbox-gl-js/api/#canvassource
Obviously you will need to determine the lat/lon of the corners of your image somehow.

Create custom map in Leaflet with coordinates

I have a historical city map that I want to display using Leaflet.
I like to set the coordinates of this image to reflect the real world, e.g so I can click on the image and get the real coordinates.
I guess I can just make it an overlay to a real map, but there must be a better solution just define at what coordinates of the corners of the image.
For this image, the approx real world coordinates is NW: 60.34343, 18.43360, SE: 60.33761, 18.44819
My code, so far, is here:
http://stage1876.xn--regrund-80a.se/example3.html
Any ideas how to proceed? It feels like it there should be an easy way to do this?
Any help would be so appreciated!
EDIT: The implementation (so far) with tiles are optional. I could go for a one image-map as well.

Efficiently draw CGPath on CATiledLayer

How would I efficiently draw a CGPath on a CATiledLayer? I'm currently checking if the bounding box of the tile intersects the bounding box of the path like this:
-(void)drawLayer:(CALayer*)layer inContext:(CGContextRef)context {
CGRect boundingBox = CGPathGetPathBoundingBox(drawPath);
CGRect rect = CGContextGetClipBoundingBox(context);
if( !CGRectIntersectsRect(boundingBox, rect) )
return;
// Draw path...
}
This is not very efficient as the drawLayer:inContext: is called multiple times from multiple threads and results in drawing the path many times.
Is there a better, more efficient way to do this?
The simplest option is to draw your curve into a large image and then tile the image. But if you're tiling, it probably means the image would be too large, or you would have just drawn the path in the first place, right?
So you probably need to split your path up. The simplest approach is to split it up element by element using CGPathApply. For each element, you can check its bounding box and determine if that element falls in your bounds. If not, just keep track of the last end point. If so, then move to the last end point you saw and add the element to a new path for this tile. When you're done, each tile will draw its own path.
Technically you will "draw" things that go outside your bounds here (such as a line that extends beyond the tile), but this is much cheaper than it sounds. Core Graphics is going to clip single elements very easily. The goal is to avoid calculating elements that are not in your bounding box at all.
Be sure to cache the resulting path. You don't need to calculate the path for every tile; just the ones you're drawing. But avoid recalculating it every time the tile draws. Whenever the data changes, dump your cache. If there are a very large number of tiles, you can also use NSCache to optimize this even better.
You don't show where the path gets created. If possible, you might try building the path up in the -drawLayer:inContext: method, only creating the portion of it needed for the tile being drawn.
As with all performance problems, you should use Instruments to profile your code and find out exactly where the bottlenecks are. Have you tried that already, and if so, what did you find?
As a side note, is there a reason you're using CGPath instead of UIBezierPath? From Apple's documentation:
For creating paths in iOS, it is recommended that you use UIBezierPath
instead of CGPath functions unless you need some of the capabilities
that only Core Graphics provides, such as adding ellipses to paths.
For more on creating and rendering paths in UIKit, see “Drawing Shapes
Using Bezier Paths.”