Jump to content
Christophe E.

ANN : TECNativeMap 5.1

Recommended Posts

I run my own OSM tile server. Currently I bundle leaflet with my application, but your component looks interesting too.
Regarding OSM you only mention setting

map.TileServer := tsOsm;

in code. But can I also specify my own tile server in the format http://example.com:8080/tile/{z}/{x}/{y}.png?

 

Edit: I found it further down: https://www.helpandweb.com/ecmap/en/tecnativemap.htm#USE_YOUR_OWN_TILE_SERVER

Edited by omnibrain

Share this post


Link to post

you can also fill a stream, for example, with a tile from a database.

 

map.TileServerInfo.getTileStream := getTileStream;

...

procedure TForm.getTileStream(const ThreadIndex:integer;var TileStream: TMemoryStream;
const x, y, z: integer);
begin
//  load tile XYZ into TileStream
end; 

 

Share this post


Link to post

Sounds great. I'm really intrigued. I'm really considering giving it a try, because currently I'm using leaflet in a web view. While that has advantages, especially for reusability in the web, a "native" Delphi solution would make my life easier especially for the simpler usecases.

 

One more question: In one part of my app I'm enriching my Map with WFS and WMS.
Via WFS I get a geojson layer and have a click handler assigned to every feature:

    var wfslayer = L.Geoserver.wfs("https://maps.dwd.de/geoserver/dwd/ows?service=WFS", {
        layers: "dwd:Warnungen_Gemeinden_vereinigt",
        style: {
            fillOpacity: 0,
        },
        onEachFeature: function (feature, layer) {
            layer.on('click', handleClick);
        }
    });
    wfslayer.addTo(map);

Via WMS I get a raster layer and use plugins to show the legend and more important navigate through the time dimension:

    var regen = L.tileLayer.wms('https://maps.dwd.de/geoserver/ows?', {
        layers: 'dwd:Niederschlagsradar',
        format: 'image/png',
        transparent: true,
        version: '1.3.0',
        opacity: 0.5,
        attribution: 'DWD'
    });
    var regen_time = L.timeDimension.layer.wms(regen, {
        updateTimeDimension: true,
    });
    regen_time.addTo(map);
    L.control.scale().addTo(map);
    uri = "https://maps.dwd.de/geoserver/ows?service=WMS&request=GetLegendGraphic&format=image%2Fpng&width=20&height=20&layer=dwd%3ANiederschlagsradar"
    L.wmsLegend(uri);

Would this be possible with your component?

 

Edit: I'm getting data from: https://maps.dwd.de/geoserver/web/ but will also use other sources in the future.

Edited by omnibrain

Share this post


Link to post

It should be possible, but not as simple as your code, because my component doesn't support WFS and WMS, so I'll have to build the query urls manually.

 

There are all the building blocks needed to create the layers, and geojson is supported, so it's easy to import the data.

 

To display meteo images, you'll need to manually build the url and use overlay tiles.

 

For legends, there's a procedure in my component to obtain a bitmap directly from a url, so it's easy enough to place a TImage on top of the component to display them.

Edited by Christophe E.

Share this post


Link to post

"Manually" building URLs for WFS is easy, because it's more or less a "static" geojson endpoint.

For WMS it is not really an option for me, because WMS (especially combined with a GeoServer) is a somewhat complex standard with spatial and temporal dimensions and way easier to use with ready made libraries.

Share this post


Link to post

A basic way of displaying the radar image is as follows


 

WMS       : TECShapeMarker;
WMS_Layer : TECNativeLayer;

...

procedure TForm6.FormCreate(Sender: TObject);
begin

 WMS_Layer := TECNativeLayer.Create(map,'WMS_dwd.de');

 WMS := WMS_Layer.Shapes.AddMarker(0,0);
 WMS.WaitAnimation := false;
 
 WMS_Layer.Observer.OnMapEndMove := MapEndMove;
 WMS_Layer.Visible := true;

end;

procedure TForm6.FormDestroy(Sender: TObject);
begin
  WMS_Layer.Free;
end;

procedure TForm6.MapEndMove(Sender: TObject);
begin
  WMS.filename := 'https://maps.dwd.de/geoserver/dwd/wms?service=WMS&version=1.1.0&request=GetMap&layers=dwd%3ANiederschlagsradar&transparent=TRUE&SRS=EPSG:4326&BBOX='+doubletostr(map.SouthWestLongitude)+'%2C'+doubletostr(map.SouthWestLatitude)+'%2C'+doubletostr(map.NorthEastLongitude)+'%2C'+doubletostr(map.NorthEastLatitude)+'&width='+inttostr(round(map.width))+'&height='+inttostr(round(map.height))+'&styles=&format=image/png';
  WMS.SetBounds(map.NorthEastLatitude, map.NorthEastLongitude, map.SouthWestLatitude, map.SouthWestLongitude);
  WMS.fitBounds := true;

end;

 

Basically, we use a marker that fills the entire map and displays the radar image we request each time we change position.

The best thing would be to create a specific layer for WMS. I'll probably add this to my todo list, but the principle is the same.

 

radar.png

Edited by Christophe E.
  • Like 1

Share this post


Link to post

Can you please provide me with a trial (your website says to ask for a trial)? I want to give it a spin, before I license it for me and my 3 other developers.

 

Native Support for WFS and WMS layers so they can be used like in leaflet without having to build the URL by hand would be great. A time dimension function for WMS, like Leaflet.TimeDimension AddOn would be the cherry on the cake.

 

Regarding the legends, you are correct, no special function is needed, they are just static images.

Share this post


Link to post

I've updated my trial version to incorporate the beginnings of WMS support.

 

You can download a trial version for Delphi 11

 

var WMS_Layer : TECNativeWMS ;

  WMS_Layer := map.AddWMSLayer('https://maps.dwd.de/geoserver/ows','dwd:Niederschlagsradar','DW');
  WMS_Layer.Visible := true;

 
  WMS_layer.Legend := true;
  WMS_layer.LegendOpacity := 75; // 0..100
  WMS_layer.LegendPosition := lpRightCenter; // lpTopLeft, lpTopRight, lpBottomLeft, lpBottomRight,lpTopCenter,lpBottomCenter,lpLeftCenter,lpRightCenter

For the time being, the only support for the time dimension will be to manually fill in the layer's Time property.

 

WMS_layer.Time := ' 2004-10-12T13:55:20Z '; // ISO 8601 - leave empty for Now

 

It's likely to evolve in the future, as this is more an alpha version than a full version.

wms.png

Share this post


Link to post

I really like what I see. Do you have an overview over the demos, so I don't have to open each one? 
Some Demos don't compile, DemoNativeLinesPolygon for example. I think it has to do with the DCUs being compiled for a different version.

Share this post


Link to post

This looks really great.
But for some demos I still get the following error, I think the uecNativeMeasureMap dcu is outdated: 
[dcc32 Fataler Fehler] UMainNativeLinesPolygones.pas(8): F2051 Unit uecNativeMeasureMap wurde mit einer unterschiedlichen Version von UECGraphics.TECCanvas compiliert

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×