Lazarus

Announcements => Third party => Topic started by: Maciej Kaczkowski on April 03, 2011, 06:57:18 pm

Title: TMapViewer
Post by: Maciej Kaczkowski on April 03, 2011, 06:57:18 pm
I'm glad to announce a new component written for Lazarus. TMapViewer is a simple component that supports the most popular maps using native graphic control.

Features:
* support Google Maps (Normal, Satellite, Hybrid, Physical, Physical hybrid)
* support OpenStreet based maps (OpenStreetMap Mapnik, OpenStreetMap Osmrenderer, OpenCycleMap)
* support Virtual Earth maps (Normal, Aerial, Road, Hybrid)
* support Yahoo maps (Normal, Satellite, Hybrid)
* lots of debug information
* pluggable download engine (synapse, native win32)
* disk caching

Download at:
http://keit.co
Title: Re: TMapViewer
Post by: Leledumbo on April 03, 2011, 07:22:47 pm
Just tried it out, nice work buddy :)
Title: Re: TMapViewer
Post by: circular on April 03, 2011, 08:38:01 pm
Cool !
Title: Re: TMapViewer
Post by: Blaazen on April 03, 2011, 09:11:22 pm
I want see it too!   ;)
It tells me
Code: [Select]
/home/v1/Lazarus_Qt/lazarus/packager/kcMapViewer.pas(1,1) Fatal: Can't find unit httpsend used by kcMapViewer
What else do I should install ?

Thanks.

It is in Synapse.  :)
Title: Re: TMapViewer
Post by: Blaazen on April 03, 2011, 10:43:06 pm
I finally compiled demo project. (on 64-bit Linux + Qt)

I was not able compile synapse as package so i only used its units.

I had to add line
Code: [Select]
{$mode objfpc}{$H+}to kcMapViewer.pas otherwise it told me:
 Error: Identifier not found "class"

Demo works fine.

Edit: I have slow internet connection. Seems this requires faster internet.
Title: Re: TMapViewer
Post by: JuhaManninen on April 04, 2011, 12:40:42 am
It works well!
The demo is very easy to port to other platforms (Linux, Mac): just change Windows unit to LCLIntf.

It is not a very big program yet works rather well. I guess you have plans to develop it further. Will it be open source?
The scrolling could be made much smoother by caching data and using threads.

Juha
Title: Re: TMapViewer
Post by: JD on April 04, 2011, 12:44:30 am
Looks very promising. Now it may be possible to write geolocalisation apps in Lazarus.  :D
Title: Re: TMapViewer
Post by: Maciej Kaczkowski on April 04, 2011, 03:00:40 pm
Thanks for testing, project will be open source (LGPL).

on my roadmap there is:
* POI
* more events OnPaint, BeforeDownload, AfterDownload
* speedup (multithread based downloading)
* more maps (virtual earth, yahoo)
Title: Re: TMapViewer
Post by: Gintas on April 04, 2011, 05:47:08 pm
Hmm and I thought it will be for game level maps :)
Title: Re: TMapViewer
Post by: cpalx on April 05, 2011, 05:12:20 am
it promises much, but it feels very slow....

I like it.
Title: Re: TMapViewer
Post by: ik on April 05, 2011, 11:46:51 am
I really liked it. I will play with it a bit more and write some demo and place it on my blog :)

Would you be willing to add this to Lazarus-CCR or a more formal repository ?
Title: Re: TMapViewer
Post by: pch on April 05, 2011, 02:47:34 pm
Very nice component, congratulation!
But I try it at work and need to set a proxy to get out to google.
So I add this code instead of using HttpGetBinary:
Code: [Select]
{$IFDEF USE_SYNAPSE}
procedure DownloadFile(const Url: string; str: TStream);
var
  HTTP: THTTPSend;
begin
  HTTP := THTTPSend.Create;
  try
    HTTP.ProxyHost:='127.0.0.1';
    HTTP.ProxyPort:='8080';
    HTTP.ProxyUser:='user';
    HTTP.ProxyPass:='password';
    if HTTP.HTTPMethod('GET', URL) then
    begin
      str.Seek(0, soFromBeginning);
      str.CopyFrom(HTTP.Document, 0);
    end;
  finally
    HTTP.Free;
  end;
end;
{$ELSE}           

It may be nice to add properties to the component to set the proxy.

Title: Re: TMapViewer
Post by: Maciej Kaczkowski on April 05, 2011, 04:36:17 pm
Quote
It may be nice to add properties to the component to set the proxy.
I found solution for this. Please wait for next version.

Quote
Would you be willing to add this to Lazarus-CCR or a more formal repository ?
I have no access and I don't know how.
Title: Re: TMapViewer
Post by: Arbee on April 05, 2011, 04:58:51 pm
What Lazarus level did you develop this with?

I tried installing it under 09.30 (I just installed that one a week ago) and I can't install mapviewer as it apparently requires fcl >= 1.0.1  and I have 1.0.

That's pretty close though ..... Could I sneakily change the .lpk file to set the dependency to 1.0?  Or will that fail big time?

Title: Re: TMapViewer
Post by: fredycc on April 05, 2011, 05:57:06 pm
Amazing Maciej Kaczkowski, thanks for you contribution, this is what I'm looking for.

Regards  :)
Title: Re: TMapViewer
Post by: PAEz on April 05, 2011, 06:00:28 pm
@Arbee
In Required Packages click on FCL and uncheck the Minimum Version and it should work fine.

Great package, works great and Im on dialup.
Title: Re: TMapViewer
Post by: Arbee on April 05, 2011, 07:30:13 pm
Thanks PAEz,
Works!

Nifty package indeed!  With adsl no problems with slow response.
Title: Re: TMapViewer
Post by: Maciej Kaczkowski on April 05, 2011, 07:51:23 pm
TMapViewer 0.2
changelog:
* Virtual Earth Maps (Normal, Aerial, Road, Hybrid)
* FCL version fix
* pluggable download engine (synapse with proxy, win32 as separate components)
* basic thread based downloading (still buggy)
* double buffering

not tested on linux
Title: Re: TMapViewer
Post by: JuhaManninen on April 06, 2011, 09:24:33 am
Quote
It may be nice to add properties to the component to set the proxy.
I found solution for this. Please wait for next version.

Quote
Would you be willing to add this to Lazarus-CCR or a more formal repository ?
I have no access and I don't know how.

You are already getting feature requests, bug reports and patches. You really should put this code into a revision control system. You can create free project in SourceForge, Coogle Code, GitHub etc...
Also, with this component you should be given access to Lazarus-CCR repository if you want.

Do you know how to use revision control systems? If not, you can learn it quickly.

Regards,
Juha
Title: Re: TMapViewer
Post by: Maciej Kaczkowski on April 06, 2011, 09:03:18 pm
Quote
Do you know how to use revision control systems? If not, you can learn it quickly.
I have only local bazaar vcs
Title: Re: TMapViewer
Post by: ik on April 06, 2011, 10:00:14 pm
The mapviewer20110405 version crashes on the threadpool code for me, on:

Code: Pascal  [Select][+][-]
  1. procedure TThreadPool.Terminate;
  2. var
  3.   i: Integer;
  4. begin
  5.   for i := 0 to FPool.Count - 1 do
  6.     TCustomThread(FPool.Objects[i]).Terminate;
  7. end;
  8.  

Regardless of my usage of threads. I'm using Lazarus 0.9.31 and FPC 2.5.1 on Linux 64 bit
Title: Re: TMapViewer
Post by: shiruba on April 08, 2011, 07:29:42 am
This project has a lot of overlap with mine (Gemba). Comparison:
Pros:
kcMapViewer - Threading (Planned for Gemba)
kcMapViewer - Native GUI Component
kcMapViewer - Temporary Memory cache of tiles
kcMapViewer - Supports more map formats.  (Possible in Gemba, but TOS disallow caching).
kcMapViewer - More Object oriented.
Pros:
Gemba - GeoLocation via PlaceEngine (Mac/Windows) or Core Location (Mac Only)
Gemba - Working on support for OpenCellID location in cooperation with certain mobile 3G routers.  (ETA 1 month)
Gemba - Libraries more neatly separated
Gemba - Disk Caching of tiles
Gemba - Tested and working on Mac OS Win32.

Both projects use Synapse, and both plan on LGPL for the libraries, so I think we should combine efforts.  kcMapviewer is more of a component, while Gemba is an application which requires a lot of libraries - but there is still a reasonable amount of overlap.

Testing kcMapViewer on Mac OS I found the following trivial issues:
1. Windows unit should be commented out.
2. cthreads needs to be added a lot of places to prevent runtime error 211.
And possibly more major issue:
Tile never seem to load, usually I see a black screen.

Source code to Gemba and Sample application will be posted shortly to:
http://www.galapagossoftware.com/developer-tools/gemba-libraries
Title: Re: TMapViewer
Post by: JuhaManninen on April 08, 2011, 09:31:36 am
Both projects use Synapse, and both plan on LGPL for the libraries, so I think we should combine efforts.  kcMapviewer is more of a component, while Gemba is an application which requires a lot of libraries - but there is still a reasonable amount of overlap.

I would love to see such combined effort.

Quote
Testing kcMapViewer on Mac OS I found the following trivial issues:
1. Windows unit should be commented out.
2. cthreads needs to be added a lot of places to prevent runtime error 211.

Those changes make it also compatible with Linux.

Juha
Title: Re: TMapViewer
Post by: cpalx on April 08, 2011, 03:56:12 pm
if you need a webpage/bugtracker page/svn i can offer my server. Even i think it is better you put it in sourcefoge or google.
Title: Re: TMapViewer
Post by: Maciej Kaczkowski on April 12, 2011, 05:42:33 pm
if you need a webpage/bugtracker page/svn i can offer my server. Even i think it is better you put it in sourcefoge or google.

thanks, i've create repository at
http://code.google.com/p/mapviewer
Title: Re: TMapViewer
Post by: Maciej Kaczkowski on April 15, 2011, 08:09:48 pm
another update 0.3
* new maps: Yahoo Normal, Hybrid, Satellite
* disk caching
* fixed bugs in threading
Title: Re: TMapViewer
Post by: d.ioannidis on May 11, 2011, 10:56:24 am
Hi,

  i have a project which will need a component like this.

  How can i work with you guys to extend it ( Overlays, Markers, Lnet as DownloadEngine for use in WinCE etc ) ?

  I've finished a project for a AVL terminal / Automotive tracker device and i've used Morfik with GoogleMaps / OpenStreet for the GUI part. I need to have a stand alone version and your component is the missing puzzle not to mention that it came the right time to change my decision from choosing .Net to choose Lazarus.

Regards,
Title: Re: TMapViewer
Post by: Phil on May 11, 2011, 07:22:03 pm
Is there a mobile strategy or angle here at all? (smart phones, tablets, etc.). That's where I'm seeing most of the interest these days - both in maps and in basic GIS functionality (some geo-processing on the device, rather than everything done on the server).

Thanks.

-Phil
Title: Re: TMapViewer
Post by: Maciej Kaczkowski on May 11, 2011, 09:33:53 pm
Quote
Is there a mobile strategy or angle here at all?
Basically I would like to create on every target where LCL works (TCustomControl control), actually I have some problems with thread pool and slow canvas.

Next step is add paths, POI. I need this component:
* for gps logger (photo tagging / track viewer) based on HOLUX M-260 or similar devices,
* to manage distributed network devices - probably visual drawing system (visio style would be great but canvas is slow and I would like not to change it)

Quote
How can i work with you guys to extend it ( Overlays, Markers, Lnet as DownloadEngine for use in WinCE etc ) ?
Whe can work on distributed vcs (hg) using code.google or svn and merge everything using patches. Currently its not a big projects so we can operate flexible (sorry for english google translate help me ;) )

-
Maciej
Title: Re: TMapViewer
Post by: Phil on May 11, 2011, 10:14:04 pm
Quote
Is there a mobile strategy or angle here at all?
Basically I would like to create on every target where LCL works (TCustomControl control), actually I have some problems with thread pool and slow canvas.

Next step is add paths, POI. I need this component:
* for gps logger (photo tagging / track viewer) based on HOLUX M-260 or similar devices,
* to manage distributed network devices - probably visual drawing system (visio style would be great but canvas is slow and I would like not to change it)

Well, if you are interested (now or in future) in mobile mapping and/or mobile GIS, there's a surprising number of options available for developers to pick from. For example, just looking at iOS, I see the following:

Every iOS device includes a "native" MapKit framework, which provides access to Google Earth/Maps:

http://developer.apple.com/library/ios/#documentation/MapKit/Reference/MapKit_Framework_Reference/_index.html

(Most mobile mapping tools are tied to the API of the server that will be serving up the maps.)

If you're not into the Google Way, Microsoft has now made Bing maps available for iOS as an Objective C control:

http://www.microsoft.com/downloads/en/details.aspx?FamilyID=6e01a102-49ed-409e-b384-0b67521fb612&pf=true

And ESRI, the Microsoft of the GIS world, also has an API for iOS:

http://resources.arcgis.com/content/arcgis-iphone/api

A free ArcGIS app is available from the App Store that allows access to maps from any ArcGIS server (for example, an ArcGIS server of your own). It also includes rudimentary GIS functionality (calculate distance, area).

http://blogs.esri.com/Dev/blogs/mobilecentral/archive/2011/03/02/ArcGIS-Application-for-iOS-v1.8-Available-On-App-Store.aspx

Thanks.

-Phil
Title: Re: TMapViewer
Post by: d.ioannidis on May 11, 2011, 10:34:24 pm

Quote
How can i work with you guys to extend it ( Overlays, Markers, Lnet as DownloadEngine for use in WinCE etc ) ?
Whe can work on distributed vcs (hg) using code.google or svn and merge everything using patches.

i'll contact you tomorrow ...

Currently its not a big projects so we can operate flexible (sorry for english google translate help me ;) )

Glad to hear that ...

[/quote]

<snip>

Well, if you are interested (now or in future) in mobile mapping and/or mobile GIS, there's a surprising number of options available for developers to pick from.

<snip>


Phil you're right and wrong.

  Basically two things come to my mind :

   1) There is no component ( that i know ) for Lazarus / Free Pascal and switching my favorite and most productive programming language is not my first option.
   2) Google or Microsoft API license. It's not open / free and most of the frameworks / components use the API extensively. I don't want to use the API ( the cost of a license is very high for me ).

regards,
Title: Re: TMapViewer
Post by: Phil on May 11, 2011, 10:43:48 pm

Phil you're right and wrong.

  Basically two things come to my mind :

   1) There is no component ( that i know ) for Lazarus / Free Pascal and switching my favorite and most productive programming language is not my first option.
   2) Google or Microsoft API license. It's not open / free and most of the frameworks / components use the API extensively. I don't want to use the API ( the cost of a license is very high for me ).

Right, you wouldn't do mobile with Lazarus, but you can use Free Pascal. Normally mobile would be a "companion" app to the desktop app, which could still be written in Lazarus.

Here's more info about using Pascal with mobile if you haven't already seen this:

http://web.me.com/macpgmr/ObjP/Xcode4/ObjP_Intro.html


I've just listed a sampling of things I've recently come across for iOS. I'm sure there are many more. And for other devices too.

Thanks.

-Phil
Title: Re: TMapViewer
Post by: luk2009 on February 07, 2012, 06:57:16 am
I'm trying to install the lpk but i received this message

Quote
Can't open include file "sswin32.inc"

what can i do?
Title: Re: TMapViewer
Post by: kirchfritz on May 18, 2012, 04:45:15 pm
Is there a code snippet how to locate the map to a given point (Long/Lat)?
The demo app always starts with showing earth.
I want to start with show my own location.

Sorry, but I dont see where to specify my coordinates as a starting point.

Can anybody help me?
Title: Re: TMapViewer
Post by: BlueIcaro on December 13, 2013, 05:07:32 pm
Hello, Is anybody working in this control?. I started to study it, and I would like is there any plans of future?

/BlueIcaro
Title: Re: TMapViewer
Post by: d.ioannidis on October 17, 2014, 09:41:51 am
Hi,

  i made a few changes to use it on linux and also i added a DownloadEngine which uses the fphttpclient.

  Very simple stuff.

PS: This is my first attempt to use mercurial.

regards,

--
Dimitrios Chr. Ioannidis
Title: Re: TMapViewer
Post by: marcov on October 17, 2014, 09:56:07 am
Has anybody made progress with offline maps from openstreetmap instead of the webservice? Is there an installable renderer?
Title: Re: TMapViewer
Post by: d.ioannidis on October 17, 2014, 10:04:45 am
Hi,

Has anybody made progress with offline maps from openstreetmap instead of the webservice? Is there an installable renderer?

AFAIU, the tmapviewer uses tiles with a very basic cache system ( saved them in local dir for reuse ). As i need also the offline feature i plan to extend the component to store the tiles as blobs to a local db.

OTOH, i found the following http://bcdcspatial.blogspot.gr/2012/01/onlineoffline-mapping-map-tiles-and.html (http://bcdcspatial.blogspot.gr/2012/01/onlineoffline-mapping-map-tiles-and.html) which is maybe a better solution, that is to run a local OSM instance.

regards,
Title: Re: TMapViewer
Post by: marcov on October 17, 2014, 10:53:37 am
The tiledrawer.com that is refered there seems to be down.
Title: Re: TMapViewer
Post by: BigChimp on October 17, 2014, 11:02:05 am
that is to run a local OSM instance.
You mean PostGIS etc? Could be done I suppose, but IIRC it's a lot of work to set up...
Title: Re: TMapViewer
Post by: d.ioannidis on October 17, 2014, 11:17:21 am
Hi,

that is to run a local OSM instance.
You mean PostGIS etc? Could be done I suppose, but IIRC it's a lot of work to set up...

well that post http://switch2osm.org/serving-tiles/manually-building-a-tile-server/ (http://switch2osm.org/serving-tiles/manually-building-a-tile-server/) is a tutotrial that i'll try this weekend. At a first read isn't such a big task IMHO.

regards,
Title: Re: TMapViewer
Post by: BigChimp on October 17, 2014, 11:26:23 am
Depends on how you look at it - if you want to use it with a single program having to install a database server seems overkill but then again PostgreSQL is capable etc.

IIRC, I saw use of spatialite (sqlite with GIS extensions) for using offline OSM as well, but have never tried to replicate it myself.
Title: Re: TMapViewer
Post by: hugoengel2003 on November 09, 2014, 06:55:11 pm
Hi,
I'm trying so hard to study mapviewer but it's being very tough!
Please, does somebody have a tutorial about this?
I really liked.
I want to locate points on map at giving lat and long from an address.
I need to create some maps using lines, too.
Anybody can help me?
Thanks.
Title: Re: TMapViewer
Post by: avra on November 10, 2014, 03:03:19 pm
Has anybody made progress with offline maps from openstreetmap instead of the webservice? Is there an installable renderer?
http://forum.lazarus.freepascal.org/index.php/topic,22103.msg133455.html#msg133455

Alternatively you can run local OpenStreetMaps server and download maps data to use it offline.
Title: Re: TMapViewer
Post by: ti_dic on December 10, 2014, 03:07:54 pm
hi,

i started playing with this component, but it's slow with UseThreads:=false. And with UseThread=true it's raise exception :(

so, i rewrited it partially. Now it use TLazIntfImage and LazRGBGraphics for multi threaded rendering and i added some function for drawing objects on map.
The "multi-threaded" component draw the map faster then the original without exception ;)
if some body is interested the sources can be found here : https://sourceforge.net/p/roadbook/code/ci/master/tree/mapviewer/

At the present moment there is no package
Title: Re: TMapViewer
Post by: Leledumbo on December 10, 2014, 04:39:34 pm
At the present moment there is no package
Should be easy to packagify, if the difference with original package is only at the rendering part. I'll take a look later since I don't have any needs for map ATM.
Title: Re: TMapViewer
Post by: ti_dic on December 10, 2014, 05:07:19 pm
No i rewrited some part from 0 because i'm new in lazarus(i'm more skilled with delphi), and i think it's a good manner to learn.

actually need the patch for issue 27144 (http://mantis.freepascal.org/view.php?id=27144) for correctly drawing

Title: Re: TMapViewer
Post by: Ocye on March 18, 2015, 03:55:18 pm
Nice component, Maciej! Hope you carry on with the development.
Esp. I wonder how to convert the long/lat coordinates into screen values. That means I'm looking for an inverse GetMouseMapLongLat() function. Reason is pretty simple: I'd like to draw into the map. Thanks in advance.
Title: Re: TMapViewer
Post by: engkin on March 18, 2015, 07:03:36 pm
Look at GetMouseMapPixel
Title: Re: TMapViewer
Post by: Ocye on March 18, 2015, 07:08:08 pm
I did. But what I want is to convert long/lat (extended) to x/y (integer) depending on zoom level.
Title: Re: TMapViewer
Post by: zeljko on March 18, 2015, 07:56:12 pm
No i rewrited some part from 0 because i'm new in lazarus(i'm more skilled with delphi), and i think it's a good manner to learn.

actually need the patch for issue 27144 (http://mantis.freepascal.org/view.php?id=27144) for correctly drawing

That issue should be moved from "Packages" to "LCL" ...
Title: Re: TMapViewer
Post by: engkin on March 18, 2015, 10:35:32 pm
I did. But what I want is to convert long/lat (extended) to x/y (integer) depending on zoom level.

SetCenterLongLat is close to what you want.

Title: Re: TMapViewer
Post by: Ocye on March 30, 2015, 03:34:11 pm
SetCenterLongLat is close to what you want.
Thanks for the tip. Here is my solution:

Code: [Select]
function TMapViewer.GetLongLatMap(AValue: TRealPoint): TIntPoint;
var
  shift: Extended;
  mx, my: Extended;
  res: Extended;
begin
  shift := 2 * pi * EARTH_RADIUS / 2.0;
  mx := AValue.X * shift / 180.0;
  my := ln( tan((90 - AValue.Y) * pi / 360.0 )) / (pi / 180.0);

  my := my * shift / 180.0;

  res := (2 * pi * EARTH_RADIUS) / (TILE_SIZE * IntPower(FZoom));

  Result.X := abs(Round((mx + shift) / res + FX)) + dx;
  Result.Y := abs(Round((my + shift) / res + FY)) + dy;
end;
dx, dy are the former local values ax, ay assigned in RepaintMap().

Would be nice to have intermediate steps of zoom by stretch drawing tiles. It's a pity that Maciej doesn't continue the project.
Title: Re: TMapViewer
Post by: magleft on December 25, 2015, 05:34:38 pm
Hi to all.
I want to use a TMapviewer comptonent but i am confused.
Can anybody send a url to dowloand ?

Thanks a lot
Title: Re: TMapViewer
Post by: engkin on December 25, 2015, 07:11:57 pm
Hi to all.
I want to use a TMapviewer comptonent but i am confused.
Can anybody send a url to dowloand ?

Thanks a lot

Maybe this post (http://forum.lazarus.freepascal.org/index.php/topic,12674.msg66284.html#msg66284) and/or this post (http://forum.lazarus.freepascal.org/index.php/topic,12674.msg164556.html#msg164556)?
Title: Re: TMapViewer
Post by: magleft on December 25, 2015, 08:22:35 pm
Thanks. Finally it's  so simple.
Title: Re: TMapViewer
Post by: Hansvb on December 26, 2015, 11:41:26 am
Is tmapviewer still maintained?
Title: Re: TMapViewer
Post by: WimVan on January 05, 2019, 11:24:43 pm
Can't install the component.  LAZGRBraphic.lpk is missing ...
Useless, that's all I can say for the moment.
Title: Re: TMapViewer
Post by: wp on January 06, 2019, 12:02:48 am
Can't install the component.  LAZGRBraphic.lpk is missing ...
Useless, that's all I can say for the moment.

Try the adaption that I put on CCR: https://sourceforge.net/p/lazarus-ccr/svn/HEAD/tree/components/lazmapviewer/. I removed the dependence on rgbagraphics, but is has a memory leak. I cannot focus on this component at the moment, and would appreciate any contributions finding this leak in these ugly threads.
Title: Re: TMapViewer
Post by: engkin on January 12, 2019, 08:15:48 pm
Can't install the component.  LAZGRBraphic.lpk is missing ...
Useless, that's all I can say for the moment.

Try the adaption that I put on CCR: https://sourceforge.net/p/lazarus-ccr/svn/HEAD/tree/components/lazmapviewer/. I removed the dependence on rgbagraphics, but is has a memory leak. I cannot focus on this component at the moment, and would appreciate any contributions finding this leak in these ugly threads.

I think the code has a few memory leaks.

TLaunchDownloadJob.ExecuteTask in unit mvEngine creates two objects (TEnvTile and TEventJob):
Code: Pascal  [Select][+][-]
  1. procedure TLaunchDownloadJob.ExecuteTask(aTask: integer; FromWaiting: boolean);
  2. ..
  3.   Queue.AddUniqueJob(TEventJob.Create
  4.     (
  5.       @Engine.evDownload,
  6.       TEnvTile.Create(FTiles[iTile], Win),
  7.       false,                                    // owns data
  8.       Engine.GetTileName(FTiles[iTile])
  9.     ),
  10.     Launcher
  11.   );
  12. ..

They do not get freed always, as seen in unit mvJobQueue:
Code: Pascal  [Select][+][-]
  1. function TJobQueue.AddUniqueJob(aJob: TJob; Launcher: TObject): boolean;
  2. ..
  3.       if Length(lst) = 0 then
  4.         Jobs.Add(aJob)  //<--- may get freed
  5.       else
  6. //will not get freed

also seen in unit mvEngine:
Code: Pascal  [Select][+][-]
  1. procedure TMapViewerEngine.evDownload(Data: TObject; Job: TJob);
  2. ..
  3.   if Job.Cancelled then
  4.     Exit; //<--- TEnvTile will not get freed
  5. ..
  6. //If it reaches here "TEnvTile" may get freed inside TileDownloaded.

There maybe other ways/sources that cause leaks.
Title: Re: TMapViewer
Post by: wp on January 12, 2019, 11:25:30 pm
I know these. But I cannot focus at this component at the moment. Patches are welcome.
Title: Re: TMapViewer
Post by: mpknap on January 17, 2019, 08:08:50 am
I have a question. Does anyone know how to calculate X and Y having Lat and Long in this component? Having geographical coordinates I want to draw something on the map at a given point.

Maciej, wiesz może? ;)
Title: Re: TMapViewer
Post by: wp on January 17, 2019, 09:52:50 am
The MapViewer component has methods LonLatToScreen and reverse ScreenToLonLat:
Code: Pascal  [Select][+][-]
  1. type
  2.   TRealPoint = Record
  3.     Lon : Double;
  4.     Lat : Double;
  5.   end;
  6.  
  7.   TMapView = class(TCustomControl)
  8.   [...]
  9.   public
  10.     function LonLatToScreen(aPt: TRealPoint): TPoint;
  11.     function ScreenToLonLat(aPt: TPoint): TRealPoint;
  12.     [...]
  13.   end;
Title: Re: TMapViewer
Post by: mpknap on January 17, 2019, 06:10:08 pm
Thanks, this component is much more extensive. I studied the "kcmapviewer" component.
I still have a problem. How to draw an ellipse on geographical coordinates, e.g. 40.00E and 15.50N?


Code: Pascal  [Select][+][-]
  1. var
  2.   p: TRealPoint;
  3.   a,b : integer;    
  4. begin
  5.   p.Lat:=15.5;
  6.   p.Lon:=40;
  7.   a:=mapview.LonLatToScreen.:=(p.Lat));
  8.   b:=mapview.LonLatToScreen(p.lon);
  9.  
  10.   mapview.Canvas.Ellipse(a,b,a+10,b+10);
  11. end;  

This code not working :/
Title: Re: TMapViewer
Post by: wp on January 17, 2019, 08:11:13 pm
No, this code is not working. In fact, I don't know how to paint into the map directly. It would be rather complicated because the map is not static and changes with zoom level and center of the map.

On the other hand, you probably want to mark some specific locations or a track. For this purpose, the MapViewer (that one by ti_dic which is in a modified version on Lazarus-CCR) has a list for GPS locations. Look at unit mvGpsObj: there is a TGpsPoint which you create with the gps coordinates as argument. Add the point to the GpsItems of the Mapviewer. You must provide some kind of ID to differentiate between the various kind of GPS items. The following code adds a GPS point for the location clicked with the mouse while the CTRL key is pressed:
Code: Pascal  [Select][+][-]
  1. const
  2.   _POINTS_ = 20;
  3.  
  4. procedure TMainForm.MapViewMouseDown(Sender: TObject; Button: TMouseButton;
  5.   Shift: TShiftState; X, Y: Integer);
  6. var
  7.   rPt: TRealPoint;
  8.   gpsPt: TGPSPoint;
  9. begin
  10.   if (Button = mbLeft) and (ssCtrl in Shift) then begin
  11.     rPt := MapView.ScreenToLonLat(Point(X, Y));
  12.     gpsPt := TGpsPoint.CreateFrom(rPt);
  13.     MapView.GPSItems.Add(gpsPt, _POINTS_);
  14.   end;
  15. end;

The point is drawn as a red cross, but you'll certainly find in the code the procedure where this is defined, and you can replace it by a circle (*).

There is also a TGpsTrack containing a list of TGpsPoints, but I did not study it yet.

To learn more about the component study ti_dic's original code in the "roadbook" application which you can see on https://sourceforge.net/p/roadbook/code/ci/master/tree/. Unfortunately, I was not able to compile the original code, I had to remove the special grid used.

(*) Drawing of the points happens in unit mvMapViewer, procedure TMapView.DrawPt.
Title: Re: TMapViewer
Post by: mpknap on January 17, 2019, 09:25:39 pm
It's not exactly about drawing  . This I will deal with later. More about converting from geographic coordinates to x, y. If we can convert X and Y, to Lon and Lat
(in the example attached to the component

Code: Pascal  [Select][+][-]
  1. procedure TMainForm.MapViewMouseMove (Sender: TObject; Shift: TShiftState;)

maybe we can go the other way.

I have a TXT file with Lat and Long entries. I want to put them on a map in any form (circle, inscription, etc.), so as to indicate that they took place in a given position.

I have the impression that it can be done with the LonLatToScreen function, but I do not understand why it does not work.

Meanwhile, thanks for the tips :)
Title: Re: TMapViewer
Post by: wp on January 17, 2019, 09:48:03 pm
The basic steps are in the preceding mail. Since you already know the coordinates, forget about the MouseDown event. You probably have a button which reads the file with the gps coordinates. At the end of the reading process you probably have something like an array "Data[]" of gps coordinates, TRealPoint. You can use the following code to draw the points in the map (not tested). The component automatically takes care of the conversion to screen coordinates. And the marks are persistent, i.e. they follow the map when you zoom or drag it to somewhere else.
Code: Pascal  [Select][+][-]
  1. uses
  2.   mvGpsObj, ...;
  3.  
  4. const
  5.   _POINTS_ = 10;
  6.  
  7. var
  8.   Data: array of TRealPt;
  9.   ...
  10.   rPt: TRealpoint;
  11.   gpsPt: TGpsPoint;
  12. begin
  13.   for rPt in Data do begin
  14.     gpsPt := TGpsPoint.CreateFrom(rPt);
  15.     MapViewer.GpsObj.Add(gpsPt, _POINTS_);
  16.   end;
  17. ...

In order to change the color you can add a property ExtraData to the gpsPt. The next code adds every other point in blue:
Code: Pascal  [Select][+][-]
  1. uses
  2.   mvExtraData, vmGpsObj, ...;
  3. var
  4.   extra: TDrawingExtraData;
  5.   i: Integer;
  6.   ...
  7. begin
  8.   for i := Low(Data) to High(Data) do begin
  9.     gpsPt := TGpsPoint.createFrom(Data[i]);
  10.     if odd(i) then begin
  11.       extra := TDrawingExtraData.Create;
  12.       extra.Color := clBlue;
  13.       gpsPt.ExtraData := extra;
  14.     end;
  15.     Mapviewer.GpsObj.Add(gpsPt, _POINTS_);
  16.   end;
   
At the moment the MapViewer can only draw crosses. But it should be possible to add a "Shape" parameter (plus, cross, circle, box, triangle) as well as some text to the ExtraData and to use these parameters when drawing the gps point. Alternatively, or better: additionally, the procedure DrawPt should be extended to fire an event OnDrawPoint(AGpsPoint: TGpsPoint) where you can draw the GPSpoint in the way you want.
Title: Re: TMapViewer
Post by: wp on January 18, 2019, 12:15:10 am
I extended the demo in https://sourceforge.net/p/lazarus-ccr/svn/HEAD/tree/components/lazmapviewer/ to show how to add GPS points to the map.
Title: Re: TMapViewer
Post by: mpknap on January 18, 2019, 06:53:44 am
Excellently!!. This is what I ment. Now from the TXT file I will load the items into the list and I can mark points on the map.
Thank you :)
This list has some limitations?

One more question. I changed the cross into an ellipse. It would be interesting to click on an ellipse (a GPS point) to display eg information in a dialog with properties (some text).
P.S.
I am writing a small program to visualize the detection of cosmic rays on a map. Detections are made by smartphones of people participating in the CREDO project of the Institute of Nuclear Physics in Krakow. I'm just a hobbyist, I do not work there.
Title: Re: TMapViewer
Post by: balazsszekely on January 18, 2019, 07:28:18 am
Quote
One more question. I changed the cross into an ellipse. It would be interesting to click on an ellipse (a GPS point) to display eg information in a dialog with properties (some text).
The idea is to create an elliptic region with the bounding rectangle's coordinates, something like this:
Code: Pascal  [Select][+][-]
  1. uses LCLIntf, LCLType;
  2.  
  3. var
  4.   Rgn: HRGN;
  5.  
  6. procedure TForm1.FormCreate(Sender: TObject);
  7. begin
  8.   Rgn := CreateEllipticRgn(75, 50, 225, 150);
  9. end;
  10.  
  11. procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  12.   Shift: TShiftState; X, Y: Integer);
  13. begin
  14.   if PtInRegion(Rgn, X, Y) then
  15.     ShowMessage('Inside ellipse')
  16.   else
  17.     ShowMessage('Outside ellipse');
  18. end;
  19.  
  20. procedure TForm1.FormPaint(Sender: TObject);
  21. begin
  22.   //just for visual feedback, you don't need this in your application
  23.   Canvas.Brush.Color := clRed;
  24.   Canvas.Ellipse(75, 50, 225, 150);
  25. end;

Quote
I am writing a small program to visualize the detection of cosmic rays on a map. Detections are made by smartphones of people participating in the CREDO project of the Institute of Nuclear Physics in Krakow.
Cool.
Title: Re: TMapViewer
Post by: wp on January 18, 2019, 09:42:36 am
I don't think that this is working because the elliptic region is tied to the Form, but not to the map. So, when the user drags the map to another location or zooms in the region will not follow the gps point.

Scanning through the source code of TMapViewer I found the following possibility. It displays the required information in a label, a pop hint should be possible as well. I added it to the demo on CCR:
Code: Pascal  [Select][+][-]
  1. procedure TMainForm.MapViewMouseMove(Sender: TObject; Shift: TShiftState;
  2.   X, Y: Integer);
  3. const
  4.   DELTA = 3;
  5. var
  6.   rArea: TRealArea;
  7.   gpsList: TGpsObjList;
  8.   L: TStrings;
  9.   i: Integer;
  10. begin
  11.   // Determine area, in GPS coordinates, around the current mouse position +/- DELTA pixels
  12.   rArea.TopLeft := MapView.ScreenToLonLat(Point(X-DELTA, Y-DELTA));
  13.   rArea.BottomRight := MapView.ScreenToLonLat(Point(X+DELTA, Y+DELTA));
  14.   // Retrieve the gps objects in this area
  15.   gpsList := MapView.GpsItems.GetObjectsInArea(rArea);
  16.   try
  17.     if gpsList.Count > 0 then begin
  18.       // Create a string from the gps objects found: Name + gps coordinates
  19.       L := TStringList.Create;
  20.       try
  21.         for i:=0 to gpsList.Count-1 do
  22.           if gpsList[i] is TGpsPoint then
  23.             with TGpsPoint(gpsList[i]) do
  24.               L.Add(Format('%s (lat=%.6f°, long=%.6f°)', [Name, Lat, Lon]));
  25.         // Assign the created string to a label caption
  26.         GPSPointInfo.Caption := L.Text;
  27.       finally
  28.         L.Free;
  29.       end;
  30.     end else
  31.       GPSPointInfo.Caption := '';
  32.   finally
  33.     gpsList.Free;
  34.   end;
  35. end;

Note that the class TGpsPoint, besides Longitude and Latitude, can also hold additional information:
Title: Re: TMapViewer
Post by: wp on January 18, 2019, 06:02:58 pm
Now I added also an event OnDrawGpsPoint to the MapViewer. It fires for each GPS point added to the GPSItems of the Mapviewer and replaces the default drawing of crosses. The event has as parameters the sending MapViewer, the canvas to draw on, as well as the GPSPoint object. Since the MapViewer in principle supports several drawing backends the canvas is given only as a TObject and must be cast to the "real" canvas used.

The following code, added to the demo project, assumes that the canvas is the FPCustomCanvas set up by default and draws a circle at the GPS point and writes its name above it:
Code: Pascal  [Select][+][-]
  1. uses
  2.   ..., FPCanvas, FPImage, IntfGraphics, ...;
  3. procedure TMainForm.MapViewDrawGpsPoint(Sender, ACanvas: TObject;
  4.   APoint: TGpsPoint);
  5. const
  6.   R = 5;
  7. var
  8.   P: TPoint;
  9.   cnv: TFPCustomCanvas;
  10.   txt: String;
  11.   w, h: Integer;
  12.   bmp: TBitmap;
  13.   img: TLazIntfImage;
  14. begin
  15.   // Screen coordinates of the GPS point
  16.   P := TMapView(Sender).LonLatToScreen(APoint.RealPoint);
  17.  
  18.   // Draw the GPS point as a circle
  19.   cnv := TFPCustomCanvas(ACanvas);
  20.   cnv.Brush.FPColor := colRed;
  21.   cnv.Ellipse(P.X-R, P.Y-R, P.X+R, P.Y+R);
  22.  
  23.   // Draw the "name" of the GPS point. Note: FPCustomCanvas, by default,
  24.   // does not support text output. Therefore we paint to a bitmap first and
  25.   // render this on the FPCustomCanvas.
  26.   txt := APoint.Name;
  27.   bmp := TBitmap.Create;
  28.   try
  29.     bmp.PixelFormat := pf32Bit;
  30.     w := bmp.Canvas.TextWidth(txt);
  31.     h := bmp.Canvas.TextHeight(txt);
  32.     bmp.SetSize(w, h);
  33.     bmp.Canvas.Brush.Color := clWhite;
  34.     bmp.Canvas.FillRect(0, 0, w, h);
  35.     bmp.Canvas.TextOut(0, 0, txt);
  36.     img := bmp.CreateIntfImage;
  37.     cnv.Draw(P.X - w div 2, P.Y - h - 2*R, img);
  38.     img.Free;
  39.   finally
  40.     bmp.Free;
  41.   end;
  42. end;  
Title: Re: TMapViewer
Post by: mpknap on January 19, 2019, 09:33:50 am
Thank you very much WP  for your help. I have what I wanted, now I will connect with the database to score points on the map.
I invite everyone interested in the CREDO project to the website :

https://credo.science/

https://github.com/credo-science

https://api.credo.science/web/

https://www.facebook.com/credo.science/

Title: Re: TMapViewer
Post by: avra on January 19, 2019, 08:18:16 pm
Now I added also an event OnDrawGpsPoint to the MapViewer.
This will be very useful. Thanks!
Title: Re: TMapViewer
Post by: WimVan on January 23, 2019, 11:29:34 am
I tried installing LazMapviewer
Then I tried using the demo ..
I got an error which I understand.  I have to pass a proxy to get info from the web.

Where can I tell that proxy is used and where can I enter the proxy-data ?

I see there is a check on the FPC $IF FPC_FullVersion >= 30101
I using
Lazarus 1.8.4
FPC Version: 3.0.4
SVN 57972


Code: Pascal  [Select][+][-]
  1. procedure TMVDEFPC.DownloadFile(const Url: string; AStream: TStream);
  2. var
  3.   http: TFpHttpClient;
  4. begin
  5.   inherited;
  6.   http := TFpHttpClient.Create(nil);
  7.   try
  8.     http.AllowRedirect := true;
  9.     http.AddHeader('User-Agent','Mozilla/5.0 (compatible; fpweb)');
  10.    {$IF FPC_FullVersion >= 30101}
  11.     if UseProxy then begin
  12.       http.Proxy.Host := ProxyHost;
  13.       http.Proxy.Port := ProxyPort;
  14.       http.Proxy.UserName := ProxyUserName;
  15.       http.Proxy.Password := ProxyPassword;
  16.     end;
  17.    {$ENDIF}
  18.     http.Get(Url, AStream);
  19.     AStream.Position := 0;
  20.   finally
  21.     http.Free;
  22.   end;
  23. end;
  24.  
Title: Re: TMapViewer
Post by: wp on January 23, 2019, 03:23:51 pm
The proxy parameters are accessible via the DownloadEngine. This is a public property of the MapView component. However, it is returned only as its fundamental type, TMvCustomDownloadEngine. TMapView creates an instance of TMvDEFpc which has the proxy properties. So, I think casting the DownloadEngine to TMvDEFpc should work:

Code: Pascal  [Select][+][-]
  1. uses
  2.   mvDLEFpc;
  3.  
  4. procedure TForm1.FormCreate(Sender: TObject);
  5. begin
  6.   with TMvDEFpc(MapView1.DownloadEngine do begin
  7.     UseProxy := true;
  8.     ProxyHost := ...
  9.     ProxyPort := ...
  10.     ProxyUsername := ...
  11.     ProxyPassword := ...
  12.   end;
  13. end;

Note that this code requires at least fpc 3.2 or fpc trunk.
Title: Re: TMapViewer
Post by: WimVan on January 23, 2019, 05:25:19 pm
Thanks, but I only have FC 3.0.4
I'll have to wait till the next update of Lazarus
Title: Re: TMapViewer
Post by: wp on January 23, 2019, 07:45:35 pm
In the new revision on CCR, I published the property DownloadEngine and added a new package which contains the download engine based on Synapse. You can put a TMvDESynapse on the form and link it to the DownloadEngine property of the MapViewer. This new DownloadEngine exposes proxy parameters even for fpc 3.0.4. You simply can set up the proxy in the Object Inspector.

Disclaimer: Proxy not heavily tested, I don't need a proxy here.

The disadvantage is that you must install a second package, lazmapviewer_synapse which depends on the synapse package (if you don't have it already install it from OPM).
Title: Re: TMapViewer
Post by: ps on February 22, 2019, 05:08:39 pm
I'm new to this component but looks great. But I have big problem with performance (I have big monitors :) ) and UI must be smooth. Resizing, scrolling all is slow as hell.

Maybe due one big component and whole screen repainting. So I have created little test app for my new concept to rewrite painting logic. Instead use one Canvas I would like to divide into TILE_SIZE parts with own map buffer.

TMapViewer will have X*Y TGraphicsControl with own buffer with WIDTH and HEIGHT of TILE_SIZE. So for one TMapViewer we will need (Width div TILE_SIZE) + 2 . Two for offscreen rendering. Same for height.

Maybe each tile can have own thread for updating to prevent queue logic :) For smooth map moving there is TTimer with 60FPS update speed to prevent lags due high mouse move speeds. Please see attachment with little concept test app. What do you thing?
Title: Re: TMapViewer
Post by: wp on February 22, 2019, 05:30:06 pm
TMapView (of lazmapviewer) already does support tiled drawing. If you don't get good speed did you activate thread support? (UseThreads := true). Threads, however, are still leaking memory at the moment. Isn't the sample demo which comes with lazmapviewer sufficiently fast?
Title: Re: TMapViewer
Post by: ps on February 22, 2019, 05:41:03 pm
This is from source code for painting (lazmapviewer):
Code: Pascal  [Select][+][-]
  1. procedure TMapView.Paint;
  2. var
  3.   bmp: TBitmap;
  4. begin
  5.   ...
  6.     bmp := TBitmap.Create;
  7.     try
  8.       bmp.SetSize(Buffer.Width, Buffer.Height);
  9.       bmp.LoadFromIntfImage(Buffer);
  10.       Canvas.Draw(0, 0, bmp);
  11.     finally
  12.       bmp.Free;
  13.     end;
  14.  ...
When I move screen 10 pixels left whole sceen must be invalidated? Or it it's possible move allready rendered screen to right and render only missing 10pixels? With even enabled DoubleBuffering POI is flickering.
I'm searching for smooth map scrolling like in web browser (or better) without too many complicated stuffs (OpenGL).
Title: Re: TMapViewer
Post by: ps on February 22, 2019, 05:46:46 pm
Isn't the sample demo which comes with lazmapviewer sufficiently fast?
Here is example of moving lazmapviewer example on full screen (2560x1440) from left to right (so all tiles are cached): laz.jpg and frame rate is about 1-2 FPS. With TImage example is 60FPS with little or no cpu usage: timage.jpg
Title: Re: TMapViewer
Post by: wp on February 22, 2019, 06:57:19 pm
Feel free to improve it.
Title: Re: TMapViewer
Post by: Awesome Programmer on March 05, 2019, 06:01:18 pm
 :o :o :o :o :o :o :o :o :o
I got an error while trying to compile a demo of TMapViewer.

It says that AllowRedirect is not a member of http and stops compiling.

am I using an old library file or something?
Title: Re: TMapViewer
Post by: wp on March 05, 2019, 06:06:24 pm
am I using an old library file or something?
How should I know?

I mean: How should I know when you don't tell us anything about the versions that you use?
Title: Is there also support for Opentopomap?
Post by: stephanweber on March 18, 2019, 03:50:54 pm
This would be great, because opentopomap gives you very beautiful maps, suitable for hiking.

Thanks, Stephan
Title: Re: TMapViewer
Post by: Awesome Programmer on March 26, 2019, 03:06:06 pm
SetCenterLongLat is close to what you want.
Thanks for the tip. Here is my solution:

Code: [Select]
function TMapViewer.GetLongLatMap(AValue: TRealPoint): TIntPoint;
var
  shift: Extended;
  mx, my: Extended;
  res: Extended;
begin
  shift := 2 * pi * EARTH_RADIUS / 2.0;
  mx := AValue.X * shift / 180.0;
  my := ln( tan((90 - AValue.Y) * pi / 360.0 )) / (pi / 180.0);

  my := my * shift / 180.0;

  res := (2 * pi * EARTH_RADIUS) / (TILE_SIZE * IntPower(FZoom));

  Result.X := abs(Round((mx + shift) / res + FX)) + dx;
  Result.Y := abs(Round((my + shift) / res + FY)) + dy;
end;
dx, dy are the former local values ax, ay assigned in RepaintMap().

Would be nice to have intermediate steps of zoom by stretch drawing tiles. It's a pity that Maciej doesn't continue the project.

OMG!!! Your simple LONG/LAT to map's screen X,Y function works FLAWLESSLY... You don't understand how many days I was rolling my head over this; searching online for hints or clues, posting on forums for a little help, trying to hack the code, even trying other versions of TMapviewer.... NOTHING got me this close to finally finishing my project that I am working on. And I don't know how I missed your post on Lazarus forum.  :-[ I got Kcmapviewer working on my system but it lacked function to go from LONG/LAT to Screen X,Y. I simply copied your function and dropped it in KcMapViewer.pas. Then, Added it to the TMapViewer Class. Changed the function to accept also DX, DY from Repaintmap procedure. BAM!!! it works like it suppose to. Thank you so much, Ocye.  :) :) :) :) :) :D :D :D :D :D
Title: Re: Is there also support for Opentopomap?
Post by: wp on April 03, 2019, 11:12:06 am
This would be great, because opentopomap gives you very beautiful maps, suitable for hiking.
OpenTopMap has been added as map provider to LazMapViewer in the recent commit.
Title: Re: TMapViewer
Post by: sstvmaster on April 23, 2019, 07:20:17 pm
Hi wp,

i want to get the map as image and then i want to print, How to do?
Title: Re: TMapViewer
Post by: wp on April 23, 2019, 10:10:45 pm
In the new revision r6861, TMapView has three new methods which extract the complete current buffer bitmap:
- function SaveToImage(AClass: TRasterImageClass): TRasterImage;
- procedure SaveToFile(AClass: TRasterImageClass; const AFileName: String);
- procedure SaveToStream(AClass: TRasterImageClass; AStream: TStream);

The demo project has a new button "Save map to file" which shows how to save the map to a file. For printing you can create a jpeg or png image and send this to the printer. Of course, don't blow it up too much, it will become fuzzy.

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. const
  3.   MARGIN = 200;
  4. var
  5.   png: TPortableNetworkGraphic;
  6.   w, h: Integer;
  7. begin
  8.   if not PrintDialog1.Execute then exit;
  9.  
  10.   png := MapView.SaveToImage(TPortableNetworkGraphic);
  11.   try
  12.     Printer.BeginDoc;
  13.     try
  14.       w := Printer.PageWidth - 2*MARGIN;
  15.       h := round(w * png.Height / png.Width);
  16.       Printer.Canvas.StretchDraw(Rect(MARGIN, MARGIN, MARGIN + w, MARGIN + h), png);
  17.     finally
  18.       Printer.EndDoc;
  19.     end;
  20.   finally
  21.     png.Free;
  22.   end;
  23. end;
Title: Re: TMapViewer
Post by: sstvmaster on April 23, 2019, 10:50:39 pm
Hi wp, many many thanks!!!  :o
Title: Re: TMapViewer
Post by: sstvmaster on April 24, 2019, 10:47:51 pm
Hi wp,

for me i have added a function FindDistance to show height and the width (in km or mi) of map area, coresponding to lat and lon.

I dont't know if this is really needed.

Code: Pascal  [Select][+][-]
  1. {
  2.  * Returns the direct distance (air-line) between two coordinates
  3.  * If Latitude NOT betwenn -90°..+90° an Longitude NOT between -180°..+180°
  4.  * the function returns -1.
  5.  * Usage: FindDistance(51.53323,-2.90130,51.29442,-2.27275,true);
  6.  * true = km, false = miles
  7. }
  8. function FindDistance(aLat, aLon, bLat, bLon: double; metric: boolean = true): double;
  9. const
  10.   raduis_km: double = 6371.0; // generalized radius of earth
  11. var
  12.   d_radians: double; // distance in radians
  13.   d_km: double;      // distance in km
  14.  
  15.   lat1r, lon1r, lat2r, lon2r: double;
  16. begin
  17.  
  18.   // Validate
  19.   if (aLat < -90.0) or (aLat > 90.0) then begin
  20.     result := -1;
  21.     exit;
  22.   end;
  23.  
  24.   if (aLon < -180.0) or (aLon > 180.0) then begin
  25.     result := -1;
  26.     exit;
  27.   end;
  28.  
  29.   if (bLat < -90.0) or (bLat > 90.0) then begin
  30.     result := -1;
  31.     exit;
  32.   end;
  33.  
  34.   if (bLon < -180.0) or (bLon > 180.0) then begin
  35.     result := -1;
  36.     exit;
  37.   end;
  38.  
  39.   // Turn lat and lon into radian measures
  40.   lat1r := (PI / 180.0) * aLat;
  41.   lon1r := (PI / 180.0) * aLon;
  42.   lat2r := (PI / 180.0) * bLat;
  43.   lon2r := (PI / 180.0) * bLon;
  44.  
  45.   // calc
  46.   d_radians := ArcCos(Sin(lat1r) * Sin(lat2r) + Cos(lat1r) * Cos(lat2r) * Cos(lon1r - lon2r));
  47.   d_km := raduis_km * d_radians;
  48.  
  49.   if metric then
  50.     result := d_km
  51.   else
  52.     result := d_km * 0.62137;
  53. end;

And this to show calculated data in label1.
Code: Pascal  [Select][+][-]
  1. procedure TMainForm.CalcVisibleWidthHeight;
  2. begin
  3.   Label1.Caption := Format('Visible width: %.2fkm', [FindDistance(
  4.                                     MapView.GetVisibleArea.TopLeft.Lat,
  5.                                     MapView.GetVisibleArea.TopLeft.Lon,
  6.                                     MapView.GetVisibleArea.TopLeft.Lat,
  7.                                     MapView.GetVisibleArea.BottomRight.Lon,
  8.                                     true)])
  9.  
  10.                                     + LineEnding +
  11.  
  12.                     Format('Visible height: %.2fkm', [FindDistance(
  13.                                     MapView.GetVisibleArea.TopLeft.Lat,
  14.                                     MapView.GetVisibleArea.TopLeft.Lon,
  15.                                     MapView.GetVisibleArea.BottomRight.Lat,
  16.                                     MapView.GetVisibleArea.TopLeft.Lon,
  17.                                     true)]);                                                ;
  18. end;

I attached the modified MapViewerDemo
Title: Re: TMapViewer
Post by: wp on April 25, 2019, 12:38:22 am
A useful addition, thank you. I added the distance calculation to unit mvEngine.
Title: Re: TMapViewer
Post by: sstvmaster on April 25, 2019, 06:34:36 pm
i get an SIGFPE Error run in IDE or "Invalid floating point operation." when start exe.

Assembler output see pic.

This is with last example from svn.
Title: Re: TMapViewer
Post by: sstvmaster on April 25, 2019, 07:17:05 pm
Hmm, thats weird.

1. copy ssl dll's
2. copy the the example dir to desktop
3. open lpi in IDE, compile (Strg+F9)
4. start exe

Error is shown -> click OK -> Window is shown without map (white screen) and no Center lat, lon.

if i comment out inside procedure TMainForm.UpdateViewportSize with { + } and then compile, there is no error message. But in the map area there is a little map in the left lower corner, and the center lat, lon is 0 (zero).

if i move or zoom in map center lat, lon is ok.

if i now recompile with no comment out then it works?

i cant understand this? %)
Title: Re: TMapViewer
Post by: wp on April 25, 2019, 07:44:36 pm
i get an SIGFPE Error run in IDE or "Invalid floating point operation." when start exe.
Improved the numerics in the new revision. Should be fixed.
Title: Re: TMapViewer
Post by: wp on April 25, 2019, 07:52:14 pm
i cant understand this?
No problem here when I follow your steps. Maybe a consquence of the SIGFPE you reported. Please update and check again.
Title: Re: TMapViewer
Post by: sstvmaster on April 25, 2019, 08:29:59 pm
now its fine. thank you  :D

a little improvement for example:

please add in var:
Code: Pascal  [Select][+][-]
  1. DirEW, DirNS: String;

and change next to this:
Code: Pascal  [Select][+][-]
  1. ...
  2.   if rPt.Lon < 0 then DirEW := ' W' else DirEW := ' E';
  3.   if rPt.Lat < 0 then DirNS := ' S' else DirNS := ' N';
  4.   InfoCenterLongitude.Caption := Format('%.6f° = %s', [rPt.Lon, GPSToDMS(rPt.Lon)]) + DirEW;
  5.   InfoCenterLatitude.Caption := Format('%.6f° = %s', [rPt.Lat, GPSToDMS(rPt.Lat)]) + DirNS;
  6. ...
  7.   if rPt.Lon < 0 then DirEW := ' W' else DirEW := ' E';
  8.   if rPt.Lat < 0 then DirNS := ' S' else DirNS := ' N';
  9.   InfoPositionLongitude.Caption := Format('%.6f° = %s', [rPt.Lon, GPSToDMS(rPt.Lon)]) + DirEW;
  10.   InfoPositionLatitude.Caption := Format('%.6f° = %s', [rPt.Lat, GPSToDMS(rPt.Lat)]) + DirNS;

LG Maik
Title: Re: TMapViewer
Post by: wp on April 25, 2019, 09:43:50 pm
Done by adding new functions LatToStr and LonToStr which add the N/S and E/W suffixes. When parameter "DMS" (= degrees, minutes, seconds) is true the string is constructed with degrees, minutes and seconds, otherwise as a normal floating point number with fractional degrees.
Title: Re: TMapViewer
Post by: sstvmaster on April 27, 2019, 03:02:22 pm
In the new example there is an StrToFloat error if try to remove a GPS point from List.

Because you try to float the DMS.

I have change the delete procedure in gpslistform.pas:
Code: Pascal  [Select][+][-]
  1. procedure TGPSListViewer.BtnDeletePointClick(Sender: TObject);
  2. var
  3.   gpsObj: TGpsObj;
  4.   gpsPt: TGpsPoint;
  5.   i: Integer;
  6.   rPt: TRealPoint;
  7. begin
  8.   if ListView.Selected <> nil then begin
  9.     gpsObj := FList[ListView.Selected.Index];
  10.     FList.Delete(ListView.Selected.Index); // remove Object from FList
  11.     ListView.Selected.Delete; // remove item from ListView
  12.     FViewer.GpsItems.Clear(_CLICKED_POINTS_);
  13.     for i:=0 to ListView.Items.Count - 1 do begin
  14.       gpsObj := FList.Items[i];
  15.       if gpsObj is TGpsPoint then begin
  16.         gpsPt := TGpsPoint(gpsObj);
  17.         rPt.Lon := gpsPt.Lon;
  18.         rPt.Lat := gpsPt.Lat;
  19.         gpsObj := TGpsPoint.CreateFrom(rPt);
  20.         gpsObj.Name := gpsPt.Name;
  21.         FViewer.GPSItems.Add(gpsObj, _CLICKED_POINTS_);
  22.       end;
  23.     end;
  24.   end;
  25. end;

It works but i dont know if its the right way.
Title: Re: TMapViewer
Post by: sstvmaster on April 27, 2019, 03:06:12 pm
I also have added in gpslistform.pas following:

Code: Pascal  [Select][+][-]
  1. procedure TGPSListViewer.BtnCalcDistanceClick(Sender: TObject);
  2. type
  3.   TCoorRec = record
  4.     Lon: Double;
  5.     Lat: Double;
  6.     Name: String;
  7.   end;
  8. var
  9.   i, iChecked: Integer;
  10.   gpsObj: TGpsObj;
  11.   gpsPt: TGpsPoint;
  12.   TCoorArr: array[0..1] of TCoorRec;
  13. begin
  14.   // count checked items
  15.   iChecked := 0;
  16.   for i:=0 to ListView.Items.Count - 1 do begin
  17.     if ListView.Items.Item[i].Checked then Inc(iChecked);
  18.   end;
  19.   //
  20.   if iChecked <> 2 then begin
  21.     ShowMessage('Please select 2 items to calculate the distance.');
  22.   end
  23.   else begin
  24.     iChecked := 0;
  25.     for i:=0 to ListView.Items.Count - 1 do begin
  26.       if ListView.Items.Item[i].Checked then begin
  27.         gpsObj := FList.Items[i];
  28.         if gpsObj is TGpsPoint then begin
  29.           gpsPt := TGpsPoint(gpsObj);
  30.           TCoorArr[iChecked].Lat := gpsPt.Lat;
  31.           TCoorArr[iChecked].Lon := gpsPt.Lon;
  32.           TCoorArr[iChecked].Name:= gpsPt.Name;
  33.           Inc(iChecked);
  34.         end;
  35.       end;
  36.     end;
  37.     // show distance between selected items
  38.     ShowMessage('Distance between ' + TCoorArr[0].Name + ' and ' + TCoorArr[1].Name + ' is: ' +
  39.     Format('%.2n %s.', [
  40.       CalcGeoDistance(
  41.         TCoorArr[0].Lat,
  42.         TCoorArr[0].Lon,
  43.         TCoorArr[1].Lat,
  44.         TCoorArr[1].Lon,
  45.         TDistanceUnits(MainForm.cbDistanceUnits.ItemIndex)
  46.         ),
  47.         MainForm.cbDistanceUnits.Items[MainForm.cbDistanceUnits.ItemIndex]
  48.       ]));
  49.   end;
  50. end;

Note!! you must set ListView Checkboxes to true and add Main form the "implementation uses".

forgot to add the zip.
Title: Re: TMapViewer
Post by: wp on April 28, 2019, 01:29:19 pm
Added with minor modification.
Title: Re: TMapViewer
Post by: sstvmaster on April 28, 2019, 05:14:12 pm
thanks and good work wp.

And whats about the exception when delete gps point? (TGPSListViewer.BtnDeletePointClick...)
Title: Re: TMapViewer
Post by: wp on April 28, 2019, 06:31:59 pm
Fixed.
Title: Re: TMapViewer
Post by: VTwin on April 28, 2019, 06:47:04 pm
Try the adaption that I put on CCR: https://sourceforge.net/p/lazarus-ccr/svn/HEAD/tree/components/lazmapviewer/.

Wow! This is fantastic.  ;D

I saw this thread a few years ago, but was not able to get anything to work. I was able to get the CCR demo running on Macintosh, after locating the synapse trunk. The colors are coming out strange on the Mac though.

I have an application that analyses spacial data, and have been using kml export to Google Earth, and links to online maps (Google, Bing, etc). I've been wanting something like this for years. Thanks to all for the work on this!
Title: Re: TMapViewer
Post by: sstvmaster on April 28, 2019, 08:35:16 pm
@wp thanks.

And i have found an bug in my TGPSListViewer.BtnCalcDistanceClick procedure.
If delete an entry in list the calculation is wrong because the list entries does not match
the actual list.

Code: Pascal  [Select][+][-]
  1. procedure TGPSListViewer.BtnCalcDistanceClick(Sender: TObject);
  2. type
  3.   TCoorRec = record
  4.     Lon: Double;
  5.     Lat: Double;
  6.     Name: String;
  7.   end;
  8. var
  9.   i, iChecked: Integer;
  10.   rPt: TRealPoint;
  11.   TCoorArr: array[0..1] of TCoorRec;
  12.   item: TListItem;
  13. begin
  14.   // count checked items
  15.   iChecked := 0;
  16.   for i:=0 to ListView.Items.Count - 1 do begin
  17.     if ListView.Items.Item[i].Checked then Inc(iChecked);
  18.   end;
  19.   //
  20.   if iChecked <> 2 then begin
  21.     ShowMessage('Please select 2 items to calculate the distance.');
  22.   end
  23.   else begin
  24.     iChecked := 0;
  25.     for i:=0 to ListView.Items.Count - 1 do begin
  26.       if ListView.Items.Item[i].Checked then begin
  27.         item := ListView.Items[i];
  28.         if TryStrToGps(item.SubItems[2], rPt.Lon) and TryStrToGps(item.SubItems[1], rPt.Lat) then
  29.         begin
  30.           TCoorArr[iChecked].Lon := rPt.Lon;
  31.           TCoorArr[iChecked].Lat := rPt.Lat;
  32.           TCoorArr[iChecked].Name:= item.SubItems[0];
  33.           Inc(iChecked);
  34.         end;
  35.       end;
  36.     end;
  37.     // show distance between selected items
  38.     ShowMessage('Distance between ' + TCoorArr[0].Name + ' and ' + TCoorArr[1].Name + ' is: ' +
  39.     Format('%.2n %s.', [
  40.       CalcGeoDistance(
  41.         TCoorArr[0].Lat,
  42.         TCoorArr[0].Lon,
  43.         TCoorArr[1].Lat,
  44.         TCoorArr[1].Lon,
  45.         DistanceUnit
  46.       ),
  47.       DistanceUnit_Names[DistanceUnit]
  48.       ]));
  49.   end;
  50. end;
  51.  
Title: Re: TMapViewer
Post by: sstvmaster on April 28, 2019, 10:41:11 pm
@wp
1.
In mvmapviewer.pas, line 165 to 217, is CopyPixels really needed as you have fixed this?

2.
could this help to fix MacOS?

mvMapViewer.pas from line 794:
Code: Pascal  [Select][+][-]
  1.   {$IFDEF WINDOWS}
  2.   //rawImg.Description.Init_BPP24_B8G8R8_BIO_TTB(AWidth, AHeight);
  3.   rawImg.Description.Init_BPP32_B8G8R8_BIO_TTB(AWidth, AHeight);
  4.   {$ELSE}
  5.   rawImg.Description.Init_BPP32_A8R8G8B8_BIO_TTB(AWidth, AHeight);
  6.   {$ENDIF}
  7.  
Title: Re: TMapViewer
Post by: wp on April 28, 2019, 11:11:39 pm
And i have found an bug in my TGPSListViewer.BtnCalcDistanceClick procedure.
If delete an entry in list the calculation is wrong because the list entries does not match
the actual list.
Fixed.

In mvmapviewer.pas, line 165 to 217, is CopyPixels really needed as you have fixed this?
The comment and bugtracker say that it is a workaround for a bug fixed after 1.8.4, i.e. the first release version having the fix must be Laz 2.0.0. This is too near for removal - otherwise all users having older versions are excluded from LazMapViewer. Look here in the forum at all the Linux users forced by their distro to ancient versions, and when a fix is already in the source there is really no reason to force them to an upgrade.

Quote
could this help to fix MacOS?

mvMapViewer.pas from line 794:
Code: Pascal  [Select][+][-]
  1.   {$IFDEF WINDOWS}
  2.   //rawImg.Description.Init_BPP24_B8G8R8_BIO_TTB(AWidth, AHeight);
  3.   rawImg.Description.Init_BPP32_B8G8R8_BIO_TTB(AWidth, AHeight);
  4.   {$ELSE}
  5.   rawImg.Description.Init_BPP32_A8R8G8B8_BIO_TTB(AWidth, AHeight);
  6.   {$ENDIF}
  7.  
I don't have access to a Mac, so I cannot check. Again: Any help is welcome, I cannot focus too much on this component. And there's still the issue with the memory leak once the viewport is dragged or the zoom has been changed (https://forum.lazarus.freepascal.org/index.php/topic,12674.msg307870.html).
Title: Re: TMapViewer
Post by: sstvmaster on April 28, 2019, 11:55:10 pm
i know that about the memory leak, i'll try to solve it. thanks again.
Title: Re: TMapViewer
Post by: VTwin on April 29, 2019, 05:23:43 pm
2.
could this help to fix MacOS?

mvMapViewer.pas from line 794:
Code: Pascal  [Select][+][-]
  1.   {$IFDEF WINDOWS}
  2.   //rawImg.Description.Init_BPP24_B8G8R8_BIO_TTB(AWidth, AHeight);
  3.   rawImg.Description.Init_BPP32_B8G8R8_BIO_TTB(AWidth, AHeight);
  4.   {$ELSE}
  5.   rawImg.Description.Init_BPP32_A8R8G8B8_BIO_TTB(AWidth, AHeight);
  6.   {$ENDIF}
  7.  

Yes, that did the trick. Thanks!

The Google Hybrid/Physical maps are displaying very dark, almost black. The Ovi maps throw an ESocketError exception: 'Host name resolution for \"c.maptile.maps.svc.ovi.com\" failed'. Maybe a cross-platform path error?

All the rest of the maps display fine. :)

Title: Re: TMapViewer
Post by: wp on April 29, 2019, 05:32:28 pm
Good.

I discovered the Google maps recently, the black maps seem to be overlays of the base maps. Could not yet figure out how to accomplish this.

The OviMaps links are outdated. They refer to Nokia maps which no longer exist. I should remove them from the code.
Title: Re: TMapViewer
Post by: VTwin on April 29, 2019, 05:59:22 pm
Good.

I discovered the Google maps recently, the black maps seem to be overlays of the base maps. Could not yet figure out how to accomplish this.

The OviMaps links are outdated. They refer to Nokia maps which no longer exist. I should remove them from the code.

Got it. Thanks for the info.

Ah yes, I remember deleting the Nokia url from my code a while back. I use a very simple scheme to display lat, lon locations by opening browser urls for: acme, bing, google, here, openstreetmap, and wikimapia. It works pretty well, but TMapViewer is way cooler.  8-)

Edit: I think Nokia is now Here (https://wego.here.com/).
Title: Re: TMapViewer
Post by: wp on April 29, 2019, 07:51:35 pm
I think Nokia is now Here (https://wego.here.com/).
Fine. But the problem is that we need to find out the exact url to these maps including the conventions how to provide longitude, latitude and zoom level. See TMapViewerEngine.RegisterProviders:
Code: Pascal  [Select][+][-]
  1.   AddMapProvider('Ovi Normal',
  2.     'http://%serv%.maptile.maps.svc.ovi.com/maptiler/v2/maptile/newest/normal.day/%z%/%x%/%y%/256/png8',
  3.     0, 20, 5, @GetLetterSvr);  
where %serv%, %x%, %y%, %z% are replaced by service-specific parameters for server, x (longitude), y (latitude) and zoom label

Google maps, for example, are downloaded by this URL: 'http://mt0.google.com/vt/lyrs=m@145&v=w2.104&x=1203&y=1538&z=12'

could this help to fix MacOS?

mvMapViewer.pas from line 794:
Code: Pascal  [Select][+][-]
  1.   {$IFDEF WINDOWS}
  2.   //rawImg.Description.Init_BPP24_B8G8R8_BIO_TTB(AWidth, AHeight);
  3.   rawImg.Description.Init_BPP32_B8G8R8_BIO_TTB(AWidth, AHeight);
  4.   {$ELSE}
  5.   rawImg.Description.Init_BPP32_A8R8G8B8_BIO_TTB(AWidth, AHeight);
  6.   {$ENDIF}
  7.  
Yes, that did the trick.

A very simple question to you: What is the define to identify Mac? The code above crashes Linux which does not like the Alpha channel byte.
Title: Re: TMapViewer
Post by: VTwin on April 29, 2019, 08:36:54 pm
I think Nokia is now Here (https://wego.here.com/).
Fine. But the problem is that we need to find out the exact url to these maps including the conventions how to provide longitude, latitude and zoom level. See TMapViewerEngine.RegisterProviders:
Code: Pascal  [Select][+][-]
  1.   AddMapProvider('Ovi Normal',
  2.     'http://%serv%.maptile.maps.svc.ovi.com/maptiler/v2/maptile/newest/normal.day/%z%/%x%/%y%/256/png8',
  3.     0, 20, 5, @GetLetterSvr);  
where %serv%, %x%, %y%, %z% are replaced by service-specific parameters for server, x (longitude), y (latitude) and zoom label

Google maps, for example, are downloaded by this URL: 'http://mt0.google.com/vt/lyrs=m@145&v=w2.104&x=1203&y=1538&z=12'

A very simple question to you: What is the define to identify Mac? The code above crashes Linux which does not like the Alpha channel byte.

Is this helpful? Tab delimited list of some I found:

Code: Pascal  [Select][+][-]
  1. MapURLs =
  2.     'http://mapper.acme.com/?ll=%s,%s&z=15&t=T' + cTab +
  3.     'http://bing.com/maps/default.aspx?cp=%s~%s&lvl=15&style=h' + cTab +
  4.     'https://copernix.io/#?where=%s,%s,14&?query=&?map_type=roadmap' + cTab +
  5.     'https://copernix.io/#?where=%s,%s,14&?query=&?map_type=hybrid' + cTab +
  6.     'http://maps.google.com/maps?ll=%s,%s&z=16&t=h' + cTab +
  7.     'http://maps.google.com/maps?ll=%s,%s&z=16&t=p' + cTab +
  8.     'https://wego.here.com/location/?map=%s,%s,15,satellite' + cTab +
  9.     'https://www.mapquest.com/latlng/%s,%s?zoom=14&maptype=map'  + cTab +
  10.     'https://www.mapquest.com/latlng/%s,%s?zoom=14&maptype=sat' + cTab +
  11.     'https://www.openstreetmap.org/?#map=15/%s/%s&layers=Q' + cTab +
  12.     'https://www.waze.com/livemap/?zoom=14&lat=%s&lon=%s' + cTab +
  13.     'http://wikimapia.org/#lat=%s&lon=%s&z=15&m=b';

The zoom levels are fixed (14 to 16), but easy enough to change. Note that copernix uses [%s,%s] = [lon,lat], the rest are [lat,lon]. All decimal degrees.

{$IFDEF DARWIN}

I don't follow the AddMapProvider format at the moment, but I'll take a closer look at the code.

EDIT: I guess now that the above urls are not helpful. :( I'll try to poke around for something useful.
Title: Re: TMapViewer
Post by: VTwin on April 29, 2019, 11:15:46 pm
I recall looking into the Google Maps api quite a few years ago, when they were making it freely available. At some point they tightened up access, and they may be rather sticky now:

https://developers.google.com/maps/faq?csw=1#tos_tiles

and may require an api key. Is there any chance that Google is blocking by blacking out the satellite image?

OpenStreetMap is friendly, but still has restrictions on use of their servers: 

https://operations.osmfoundation.org/policies/tiles/

I guess any end application would have to look closely at the legalese. :(

Title: Re: TMapViewer
Post by: avra on April 29, 2019, 11:30:19 pm
OpenStreetMap is friendly, but still has restrictions on use of their servers
You can download OSM maps and render them locally. You can not do that with Google Maps.
Title: Re: TMapViewer
Post by: VTwin on April 29, 2019, 11:49:37 pm
OpenStreetMap is friendly, but still has restrictions on use of their servers
You can download OSM maps and render them locally. You can not do that with Google Maps.

It looks to me that TMapViewer downloads rendered tiles though, as opposed to vector and raster data. Is that not the case?
Title: Re: TMapViewer
Post by: wp on April 30, 2019, 12:04:51 am
Yes. You can find them as png in the cache folder of the demo application.
Title: Re: TMapViewer
Post by: VTwin on April 30, 2019, 12:07:41 am
Yes. You can find them as png in the cache folder of the demo application.

Nice!
Title: Re: TMapViewer
Post by: VTwin on April 30, 2019, 12:11:03 am
This may not be useful, as you have already included such a function, but this is a slightly different distance function I use:

Code: Pascal  [Select][+][-]
  1. { LatLongToDistance
  2.   Uses the Haversine formula to calculate the great-circle distance between
  3.   two points. Bearing is the initial bearing. Uses mean spherical earth radius.
  4.   Distance is in meters, angles are in radians. Earth model is FAI (Fédération
  5.   Aéronautique Internationale) Sphere.
  6.   Ref:
  7.     http://www.movable-type.co.uk/scripts/latlong.html
  8.     http://edwilliams.org/gccalc.htm}
  9. procedure LatLongToDistance(const lat0, long0, lat1, long1: double;
  10.   var dist, bearing: double);
  11. var
  12.   R: double = 6371000.0; // Earth radius in meters
  13.   dlat, dlong, slat, slong, a, c, x, y: double;
  14. begin
  15.   // dist
  16.   dlat := lat1 - lat0;
  17.   dlong := long1 - long0;
  18.   slat := Sin(0.5 * dlat);
  19.   slong := Sin(0.5 * dlong);
  20.   a := slat * slat + Cos(lat0) * Cos(lat1) * slong * slong;
  21.   c := 2.0 * ArcTan2(Sqrt(a), Sqrt(1.0-a));
  22.   dist := R * c;
  23.   // bearing
  24.   y := Sin(dlong) * Cos(lat1);
  25.   x := Cos(lat0) * Sin(lat1) - Sin(lat0) * Cos(lat1) * Cos(dlong);
  26.   bearing := ArcTan2(y, x);
  27. end;    

Title: Re: TMapViewer
Post by: VTwin on April 30, 2019, 12:39:41 am
For symmetry:

Code: Pascal  [Select][+][-]
  1. { DistanceToLatLong
  2.   Given a point defined by (lat,long), a distance and compass bearing, return
  3.   the coordinate of the resulting destination point. Uses mean spherical earth
  4.   radius. Angles are in radians, distances in meters.
  5.   Ref: http://www.movable-type.co.uk/scripts/latlong.html }
  6. procedure DistanceToLatLong(const lat0, long0, dist, bearing: double;
  7.   var lat1, long1: double);
  8. var
  9.   R: double = 6371000.0; // earth radius in meters
  10.   d, x, y: double;
  11. begin
  12.   d := dist/R; // angular distance
  13.   lat1 := ArcSin(Sin(lat0) * Cos(d) + Cos(lat0) * Sin(d) * Cos(bearing));
  14.   x := Cos(d) - Sin(lat0) * Sin(lat1);
  15.   y := Sin(bearing) * Sin(d) * Cos(lat0);
  16.   long1 := long0 + ArcTan2(y, x);
  17. end;  
Title: Re: TMapViewer
Post by: wp on May 01, 2019, 12:32:50 am
Found some documentation for the HERE maps (https://developer.here.com/documentation/map-tile/topics/introduction.html) and managed to integrate some variants into the MapViewer. Note, however, that (free) registration is required at https://developer.here.com/. After registration you'll receive an APP_ID and an APP_CODE; open the ini file of the demo program (in its exe folder) and add a section with the corresponding information (replace ABC and xyz by the strings sent to you by HERE):

Code: [Select]
[HERE]
APP_ID=ABC
APP_CODE=xyz

When you run the demo program the next time the HERE maps will be included in the map provider drop down. Unfortunately, ATM, it seems that the parameters are not yet inserted correctly into the URL, and there are a lot of drawing artefacts.

Another issue is that I do not get the fphttpclient to accept the https url. Therefore, I used the synapse downloader in the demo for the moment.
Title: Re: TMapViewer
Post by: sstvmaster on May 01, 2019, 12:33:43 pm
Another issue is that I do not get the fphttpclient to accept the https url. Therefore, I used the synapse downloader in the demo for the moment.

Can you give me a short example, please? Is the issue with all urls, or only with the HERE url?
Title: Re: TMapViewer
Post by: wp on May 01, 2019, 12:49:02 pm
HERE url only. The fphttpclient downloader reports the error: 'Project MapViewer_Demo raised exception class 'ESocketError' with message: Host name resolution for "0.base.maps.api.here.com" failed"'; the Synapse downloader works correctly.

Playing again with these maps and having this error message in mind, I get the idea that maybe the "0" in "0.base.maps..." is not valid; I replaced the %serv% in the AddMapProvider call (in TMapViewerEngine.RegisterProviders) by a hard-coded "1", and now also the fphttpclient works correctly, and even the drawing artefacts due to missing tiles that I reported yesterday are gone. So, the remaining problem is: How to convince the component to not generate URLs with a leading "0".
Title: Re: TMapViewer
Post by: sstvmaster on May 01, 2019, 12:54:50 pm
I get the idea that maybe the "0" in "0.base.maps..." is not valid;

It is not valid, see api: https://developer.here.com/documentation/map-tile/topics/resource-base-basetile.html

EDIT: And here: https://developer.here.com/documentation/map-tile/topics/load-balancing-and-urls.html
Title: Re: TMapViewer
Post by: wp on May 01, 2019, 05:45:05 pm
The function GetYahooSvr is constructed such as to create server numbers starting at 1 instead of 0. Putting this into the AddMapProvider for the HERE mapes calls gives error-free access to these maps (provided that the HERE credentials have been obtained and have been made known to the demo program).
Title: Re: TMapViewer
Post by: Alekos on May 11, 2019, 05:40:48 pm
Hi anyone has an example of TGPSTrack ?
Cant find anything.
Thanks!!!
Title: Re: TMapViewer
Post by: wp on May 12, 2019, 11:52:42 pm
A GPSTrack is a list a GPSPoints. Therefore, in order to create a GPSTrack you must create GPSPoints first and then add them to the Points list of the GPSTrack. Finally you add the track to the GPSItems of the viewer; give it a unique number to identify the track.

I added an example to the demo program of the MapViewer; find the code in unit gpslistform. At first add some gps points to the Viewer (by right-clicking at the track points). Then click "GPS points..." and "Save points" to save the points to a simple track file (just a tab-delimited file). When you want to see the track later, click again "GPS points..." and then "Load track".

[EDIT]
Added a parser for GPX files. In the demo there is a new button "Load GPX file" from which you can select your own GPX files or those downloaded from the internet (e.g.: http://www.gpsvisualizer.com/examples/google_gpx.html); the mapviewer will then display track, route and waypoints. When I have more time I'll add some machinery to assign particular icons to way points, e.g. trail head, mountain peak, etc.
Title: Re: TMapViewer
Post by: JosepB on June 10, 2019, 05:43:44 pm
Thank you very much for the component, it works very well and every day is more complete. However, I wanted to make a suggestion to the developer, wp: would it be useful to add to the TGPSObj object a property with the IdOwner value in order to easily differentiate the different created and existing objects on the map ?.
Title: Re: TMapViewer
Post by: wp on June 13, 2019, 12:13:54 am
I made GpsObj.IdOwner public now. Is that ok for your needs?
Title: Re: TMapViewer
Post by: JosepB on June 13, 2019, 12:11:27 pm
Thank you!.
Title: Re: TMapViewer
Post by: immoblecher on May 15, 2020, 11:06:31 am
This is a very useful component and I could only try it out now. :( I even got it right to display points in different colours depending on the ELE value. But what I could not get right is to display the NAME as a label. I saw in the examples that there were some attempts with the ADrawer TextOut and TextExtent functions/procedures but they are not working and I guess therefore commented out. Trying to use them crash the application with lots of Access Violations. Anyone any other ideas on how one could display the labels? @wp: are you still working on that? That would be the jewel in the crown. ;)
Title: Re: TMapViewer
Post by: winni on May 15, 2020, 12:53:14 pm
For symmetry:

Code: Pascal  [Select][+][-]
  1.  
  2. procedure DistanceToLatLong(const lat0, long0, dist, bearing: double;
  3.   var lat1, long1: double);
  4. var
  5.   R: double = 6371000.0; // earth radius in meters
  6.   d, x, y: double;
  7. begin
  8.   d := dist/R; // angular distance
  9.   lat1 := ArcSin(Sin(lat0) * Cos(d) + Cos(lat0) * Sin(d) * Cos(bearing));
  10.   x := Cos(d) - Sin(lat0) * Sin(lat1);
  11.   y := Sin(bearing) * Sin(d) * Cos(lat0);
  12.   long1 := long0 + ArcTan2(y, x);
  13. end;  

Hi!

This needs some speedup - there are situations where it is heavily used.

* Some values are computed twice with sin or cos -
  you can compute theses variables first
* To speedup you can do math.sincos where sinus and cosinus are
  computed in one job.
* We should take the latest exact value for the earth radius from WGS84 = 6378137.0 meters

Code: Pascal  [Select][+][-]
  1. procedure DistanceToLatLong(const lat0, long0, dist, bearing: double;
  2.                                              var lat1, long1: double);
  3.  
  4. var
  5.   //R: double = 6371000.0; // earth radius in meters
  6.   R : double =  6378137.0; // WGS84
  7.   d, x, y: double;
  8.   cosd, sind, coslat0, sinlat0 : double;
  9. begin
  10.   d := dist/R; // angular distance
  11.   math.sincos (d,sind,cosd);
  12.   math.sincos (lat0,sinlat0, coslat0);
  13.   lat1 := ArcSin(sinlat0 * cosd + coslat0 * sind * cos(bearing) );
  14.   //lat1 := ArcSin(Sin(lat0) * Cos(d) + Cos(lat0) * Sin(d) * Cos(bearing));
  15.   x := cosd - sinlat0 * sin(lat1);
  16.   //x := Cos(d) - Sin(lat0) * Sin(lat1);
  17.   y := sin(bearing) * sind * coslat0;
  18.   //y := Sin(bearing) * Sin(d) * Cos(lat0);
  19.   long1 := long0 + ArcTan2(y, x);
  20. end;                                  
  21.  

And don't forget:

The earth is an ellipsoid - at the poles the radius is about 21 km less than at the equator.
(So it's easierer for the Trolls from Midearth to the surface ....)

This can lead to 0.5% deviation.

Winni
Title: Re: TMapViewer
Post by: wp on May 15, 2020, 01:32:13 pm
The earth is an ellipsoid - at the poles the radius is about 21 km less than at the equator.
... This can lead to 0.5% deviation.
So then, why do you care about the difference between 6371000 and 6378137 when you do not use the exact formula for an ellipsoid? And even worse, as wikipedia shows (https://en.wikipedia.org/wiki/Earth_radius#Published_values), the former value is almost exactly the radius of the "average" sphere (having the same volume as the ellipsoid) while your value is the radius at the equator (major axis). Using this will overestimate all distances (except for those near the equator) while the former one leads to a more evenly distributed error.

There is one more optimization: since lat1 is the arcsin of some expression it is not necessary to calculate sin(lat1) because that is just the value of that expression put into the arcsin as argument.
Code: Pascal  [Select][+][-]
  1. procedure DistanceToLatLong(const lat0, long0, dist, bearing: double; var lat1, long1: double);
  2.  
  3. var
  4.   R: double = 6371000.0; // earth radius in meters
  5.   d, x, y: double;
  6.   cosd, sind, coslat0, sinlat0, sinlat1: double;
  7. begin
  8.   d := dist/R; // angular distance
  9.   math.sincos (d,sind,cosd);
  10.   math.sincos (lat0,sinlat0, coslat0);
  11.   sinlat1 := sinlat0 * cosd + coslat0 * sind * cos(bearing);
  12.   x := cosd - sinlat0 * sinlat1;
  13.   y := sin(bearing) * sind * coslat0;
  14.   lat1 := ArcSin(sinlat1);
  15.   long1 := long0 + ArcTan2(y, x);
  16. end;

But: I just wanted to update the source, but there is no DistanceToLatLong() anywhere within LazMapviewer. So, what are you talking about?
Title: Re: TMapViewer
Post by: winni on May 15, 2020, 02:02:07 pm
@wp

I'm talking about VTwins posting.
Sometimes reading helps.

About the earth radius:

The international astronomical SI unit is
6.3781×10^6 m

In geophysics the mean radius is defined as
 6.371.0088 m

And Erastothenes computed around 200 BC a value of
6.645 km
- not bad.

Winni
Title: Re: TMapViewer
Post by: wp on May 16, 2020, 08:04:58 pm
This is a very useful component and I could only try it out now. :( I even got it right to display points in different colours depending on the ELE value. But what I could not get right is to display the NAME as a label. I saw in the examples that there were some attempts with the ADrawer TextOut and TextExtent functions/procedures but they are not working and I guess therefore commented out. Trying to use them crash the application with lots of Access Violations. Anyone any other ideas on how one could display the labels?
It's been some time since I was in the depths of this component... Normally it is enough to "add" a TGpsPoint to the GpsItems of the MapView, and the drawing engine will take care of the drawing. This is the code from the demo program where a point can be marked by a right click:
Code: Pascal  [Select][+][-]
  1. procedure TMainForm.MapViewMouseUp(Sender: TObject; Button: TMouseButton;
  2.   Shift: TShiftState; X, Y: Integer);
  3. var
  4.   rPt: TRealPoint;
  5.   gpsPt: TGpsPoint;
  6.   gpsName: String;
  7. begin
  8.   if (Button = mbRight) then begin
  9.     if not InputQuery('Name of GPS location', 'Please enter name', gpsName) then
  10.       exit;
  11.     rPt := MapView.ScreenToLonLat(Point(X, Y));
  12.     gpsPt := TGpsPoint.CreateFrom(rPt);
  13.     gpsPt.Name := gpsName;
  14.     MapView.GpsItems.Add(gpsPt, _CLICKED_POINTS_);
  15.   end;
  16. end;

The points added this way are marked by a "+". If you assign a bitmap to the POIImage property of the MapView it will be drawn instead. However, there is even more. The TGpsPoint has a general property "ExtraData" which can be used for any purpose to provide further parameters how the POI is drawn. The package comes with the TDrawingExtraData in unit mvExtraData which provides access to the color of the POI and which is automatically respected by the map viewer. For additional parameters you must provide a handler for the OndrawGPSPoint event where you can read the extra data and draw a symbol accordingly.

Since this sounds maybe a bit complicated I just extended the demo project (in folder "examples") with complete routines for it, everything happens in the OnMouseUp and OnDrawGPSPoint events. Go to page "Config" of the demo and select "custom drawing" in the POI mode box. Then right-click somewhere in the map, a dialog will appear in which you can select how the POI is to be displayed.

The new version is in the trunk svn repository of ccr, or, if you do not use svn, download the snapshot from https://sourceforge.net/p/lazarus-ccr/svn/HEAD/tree/components/lazmapviewer/. It is NOT yet available through OPM.
Title: Re: TMapViewer
Post by: Adromir on May 20, 2020, 03:22:26 pm
I was trying to Install the TMapViewer to my Lazarus Installation but I havent been really succesfull to do so. First I went to an error, that the Package couldnt be compiled due to a missing Unit, which I solved by Adding FCL to the Package dependencies. But Now I am trying to open the Demo project and all I am getting is "Can't find component class TMVGeoName. It wasn't registered by RegisterClass and no lfm was found". Can someone please help me to solve this? Installing via OPM also fails because of the Missing FCL dependency
Title: Re: TMapViewer
Post by: wp on May 20, 2020, 03:27:21 pm
I hope you are talking about the LazMapViewer package, there are others on which LazMapViewer is based but they are outdated and not maintained.

The easiest way to install the package is to open Online Package Manage (from the Package menu), scroll down a bit and check the "LazMapViewer" item, click install, follow the instructions and wail until the IDE is rebuilt and restarted.
Title: Re: TMapViewer
Post by: sstvmaster on May 20, 2020, 06:45:15 pm
The same error here with 2.0.8/3.0.4, tried to install via OPM.

Edit:  Also with fixes/fixes.
Title: Re: TMapViewer
Post by: wp on May 20, 2020, 08:05:33 pm
Yes, the new package structure again... I uploaded a fix to CCR (https://sourceforge.net/projects/lazarus-ccr/files/LazMapViewer/lazmapviewer-v0.2.2.1.zip/download) and asked GetMem to update the version in OPM.
Title: Re: TMapViewer
Post by: sstvmaster on May 20, 2020, 08:40:36 pm
Thanks wp, manual installation works fine, thumbs up!
Title: Re: TMapViewer
Post by: wp on May 20, 2020, 10:17:21 pm
As GetMem wrote in the OPM thread, the new version is now distributed by OPM as well.
Title: Re: TMapViewer
Post by: Adromir on May 21, 2020, 12:00:12 am
Thank you, installing and using it works like a charm now. Just wondering, is it possible to draw a circle on the map around a location with a certain radius? That would be exactly the feature I need for my project
Title: Re: TMapViewer
Post by: mpknap on October 07, 2020, 06:04:31 pm
How to load and display coordinates on map,  from SQLITE file?
Title: Re: TMapViewer
Post by: cpalx on October 07, 2020, 07:00:53 pm
@mpknap

you hace some examples in the same directory of Tmapviwer files
Title: Re: TMapViewer
Post by: mpknap on October 07, 2020, 08:03:49 pm
@mpknap

you hace some examples in the same directory of Tmapviwer files

I can't see anything from DB / SQLITE there. Are we writing about it?
https://sourceforge.net/projects/lazarus-ccr/files/LazMapViewer/
Title: Re: TMapViewer
Post by: wp on October 07, 2020, 09:46:44 pm
You are right, the sample application does work with a database. But it shows how you can draw a marker at given coorindates in the map. So, you only must extract your coordinates from the database and follow the sample code.
Title: Re: TMapViewer
Post by: mpknap on October 08, 2020, 10:42:30 am
You are right, the sample application does work with a database. But it shows how you can draw a marker at given coorindates in the map. So, you only must extract your coordinates from the database and follow the sample code.

this work fine and dispaly points :
Code: Pascal  [Select][+][-]
  1. procedure TMainForm.Button1Click(Sender: TObject);
  2.  var
  3.   ds: TDataset;
  4.   team,latt, lonn: TField;
  5.   x, y: double;
  6.   gpsPt: TGpsPoint;
  7.   a,b : string;
  8. begin
  9.   SQLQuery1.SQL.Clear;
  10.   dbgrid1.Clear;
  11.   SQLite3Connection1.DatabaseName :=
  12.     'C:\DataCenter\Data\AF_2019_01_0101_00_00do2019_01_0215_38_08.sqlite';
  13.   SQLite3Connection1.Connected := True;
  14.   SQLTransaction1.DataBase := SQLite3Connection1;
  15.   SQLQuery1.DataBase := SQLite3Connection1;
  16.   SQLQuery1.PacketRecords := 500000;
  17.  
  18.   SQLTransaction1.Active := True;
  19.  
  20.   SQLQuery1.SQL.Text := 'SELECT latitude,lonngitude, user_id from detections ';
  21.   SQLQuery1.Close;
  22.   SQLQuery1.Open;
  23.   DataSource1.DataSet := SQLQuery1;
  24.  
  25.   DBGrid1.DataSource := DataSource1;
  26.   DBGrid1.AutoFillColumns := true;
  27.  
  28.   ds := DBGrid1.Datasource.Dataset;
  29.   ds.DisableControls;
  30.  
  31.   try
  32.     latt := ds.FieldByName('latitude').;
  33.     lonn := ds.FieldByName('lonngitude');
  34.  
  35.     team := ds.FieldByName('user_id');
  36.     ds.First;
  37.     while not ds.EOF do
  38.     begin
  39.        gpsPt := TGpsPoint.Create(strtofloat(stringReplace(lonn.AsString, '.', ',',
  40.        [rfReplaceAll])), strtofloat(stringReplace(latt.AsString, '.',      ',', [rfReplaceAll])));
  41.  
  42.        gpsPt.Name := team.AsString;
  43.         MapView.GpsItems.Add(gpsPt, 0);
  44.        ds.Next;
  45.     end;
  46.     a:=ds.FieldByName();
  47.   finally
  48.  
  49.     ds.EnableControls;
  50.   end;
  51. end;  


Title: Re: TMapViewer
Post by: sstvmaster on December 19, 2020, 08:09:11 pm
Error in "example_with_addons": LazRGBGraphics not found. It is available here: https://sourceforge.net/projects/lazarus-ccr/files/LazRGBGraphics/ but very old.

Tested with Laz 2.0.10 and Trunk (r64230)
Title: Re: TMapViewer
Post by: wp on December 19, 2020, 09:45:57 pm
Oh, I think I understand. Recently I had to set up my new computer and noticed that the rgbgraphics package needed by MapViewer was not found. I thought that the development version is the one on ccr and I selected it without thinking... Your comment reminds me that there is another version, and now I know that it is in OPM with a different name. What a mess!

Since OPM is the primary package source now I think I should revert it to the OPM name. But on the other hand where does this OPM version come from? I am pretty sure that it is a CodeTyphon import because there are "ct9999" comments in two files. Luckily the files are identical except for two little changes in the non-ccr versions which easily can be merged.

So, what to do? The problem is that there are two packages with the same content but different names. The one on the popular OPM server is from a source to which we do not have access. I'd prefer to replace this package by the one from ccr which we can maintain although the package seems to be abondoned by its original author. This will present users with package not found errors, however. On the other hand, rgbgraphics is a runtime package and needs no installation. I am rather sure that it should be possible to distribute both packages in OPM. I'll have to contact GetMem...
Title: Re: TMapViewer
Post by: CV on April 03, 2022, 03:03:55 pm
I'm brand new to this forum, therefore sorry if my request is not properly placed..
I've played around with MapView for quite a while on Windows and Raspberry. Many thanks to all creators and supporters for all the wunderfull functions!

My questions: Is there a way to apply a (digital) zoom factor to the drawing canvas itself? To stretch each of the 256x256 tiles to a (e.g) 512x512 pixels?
Or where would be the best place to access the respective canvas code and insert my own additional copy and zoom code? I'm a bit lost by the huge amount of files and wasn't able to track it down..

Why? For simple magnification for better visibility. My display is physically small and a digital zoom would help very much to recognize tiny details. My application is intended for offline use. All tiles have been created upfront (for my area of interest) and stored to the cache folder. To limit the amount of tiles I've restricted the zoom level to 15. Therefore it is not possible to just go to the next tiles' zoom level.

Many thanks in advance.
Title: Re: TMapViewer
Post by: wp on April 03, 2022, 03:21:47 pm
I suppose you are talking of the LazMapViewer package. The tiles are delivered from the server as 256x256 png bitmapped images. There is no easy way to upscale the images in order to better resolve details - normally the images just get blurry. I don't know what they do in the movies when the hero asks the assistant to zoom in further so that the tiny license plate becomes readable...

If you somehow manage to get 512x512 images of good quality, it is possibly enough to simply change the constant TILE_SIZE in unit mvTypes to 512.

Title: Re: TMapViewer
Post by: marcov on April 03, 2022, 03:41:57 pm
Use opengl and hw anti aliassing?
Title: Re: TMapViewer
Post by: CV on April 03, 2022, 03:51:02 pm
Yes, the LazMapViewer package :-[

I will check the 512x512 option, thanks for the hint.

For now I'm applying a workaround. On each "OnChange" event of the MapViewer component I copy the canvas to a larger one (CopyRect), thus magnifying it. But that is not really synchronised, I assume due to the Threading.
Do you have a better code position (than in main.pas) in mind to do this?

Yes, blurrying is starting to become visible. But 2x magnification is all I need.

Btw, I'm already running two MapViewer components in parallel, at different zoom levels. Works great and smooth :).
Title: Re: TMapViewer
Post by: bobby100 on April 03, 2022, 04:02:54 pm
I don't know what they do in the movies when the hero asks the assistant to zoom in further so that the tiny license plate becomes readable...
There was a program that converted image to fractals (ca. 1996-1997, I got it from some BBS). It replaced the tiles of BMP with appropriate fractals. The generated fractalized pictures were at least 10x more "zoomable" than a BMP.
A fractalized picture looks somewhat synthetic compared to the original (something like a bad anti-aliasing). By zooming over some extent, you could see the fractals that all of us know.
Nothing like the zoom in the movies, but still something.

Related:
https://en.wikipedia.org/wiki/Fractal_compression

I apologize for going off-topic
Title: Re: TMapViewer
Post by: CV on April 22, 2022, 08:56:46 pm
I'm still playing with and learning from the examples that come the LazMapViewer package.
Another question came up about the handling of GpsItems. I've create such an object with the following code:
Code: Pascal  [Select][+][-]
  1. procedure TMainForm.btCreatePointClick(Sender: TObject);
  2. var
  3.   rPt: TRealPoint;
  4.   gpsPt: TGpsPoint;
  5.   gpsName: String = '';
  6. begin
  7.   rPt := MapView.Center;
  8.   gpsPt := TGpsPoint.CreateFrom(rPt);
  9.   gpsPt.Name := '';
  10.   MapView.GpsItems.Add(gpsPt, _CLICKED_POINTS_);
  11. end;  
So far so good. The marker appears where it should be (at the center of the screen). It also shows up correctly in the GPS points list (part of the example). 
Next I've moved the window a bit and tried to move/change the location of the GpsObject to the new center by applying:
Code: Pascal  [Select][+][-]
  1. procedure TMainForm.btRelocateToCenterClick(Sender: TObject);
  2. var
  3.   rPt: TRealPoint;
  4.   gpsObj: TGpsObj;
  5. begin
  6.   rPt := MapView.Center;
  7.   if (MapView.GpsItems.Count > 0) then begin
  8.     gpsObj := MapView.GpsItems[0];
  9.     if gpsObj is TGpsPoint then begin
  10.       TGpsPoint(gpsObj).MoveTo(MapView.Center.Lon, MapView.Center.Lat, NO_ELE ,NO_DATE );
  11.     end;
  12.   end;
  13. end;
From now on the painting of the marker get's weird, or disappears completely, also depeding on zoom level.
What am I doing wrong?
Title: Re: TMapViewer
Post by: wp on April 23, 2022, 07:02:01 pm
Did you try to call MapView.Redraw at the end of btRelocateToCenterClick?
Title: Re: TMapViewer
Post by: CV on April 24, 2022, 09:58:52 am
No improvement with .Redraw.
I've also altered the settings for DrawingEngines, Threads and Double Buffering: no improvement.

The workaround I found is to clear the list and create a new entry with updated coordinates:
Code: Pascal  [Select][+][-]
  1.       MapView.GpsItems.Clear(_CLICKED_POINTS_);
  2.       gpsObj := TGpsPoint.CreateFrom(rPt);
  3.       gpsObj.Name := '';
  4.       MapView.GPSItems.Add(gpsObj, _CLICKED_POINTS_);
  5.  

(This marker shows the current GPS-position. New coordinates about every 0.5 second)
Title: Re: TMapViewer
Post by: wp on April 24, 2022, 11:42:38 am
I cannot reproduce this - although I agree that sometimes the markers disappear. This is a consequence of the tiled painting routine which draws the map tile by tile in individual threads and unpredictable order, and puts the markers on top of it which may be overwritten if the image tile is painted later. I think the painting routine requires a major overhaul...

Since you have to erase the marker list I assume that you already have some markers before your code is executed. Please be aware that gpsObj := MapView.GpsItems[0] refers to the first marker added which is not necessarily the one you are interested in.
Title: Re: TMapViewer
Post by: CV on April 24, 2022, 03:46:36 pm
Maybe the drawing routine somehow memorizes the GPS location when adding/creating a new element?..
Btw, my workaround idea was inspired by the GPSListViewer (TGPSListViewer.BtnDeletePointClick, deleting a point from the list).
(And thanks, I'm aware of affecting all elements of the list)


All in all I'm still very happy how nice and smooth this component works. Keeping the effort in mind it took to come to this level I feel a bit bad to propose some improvements. Also the idea contradicts the tiles-approach. But this would be my wishlist:

For offline usage it's a pain to handle all the tiles. Even for small areas I have to deal with several 100k of tiles/files. Would it be possible to get the data out of one single file (regardless its size)? I've seen this approach based on vector data:
https://github.com/serbod/osmap
Title: Re: TMapViewer
Post by: CV on May 25, 2022, 08:55:09 pm
I've been playing around with MapViewer for some weeks now and want to share my observations, .. and problems. My main machine is a typical Win10-64 bit. The second (and final) target is a small tablet Win10-32 bit, 1GB RAM, Intel Atom Z3735G processor.
All tiles are stored in the disk-cache, online connection is not used.
At a first glance the component works as expected and smoothly.

But randomly an exceptions is raised when shutting down: "External: ACCESS VIOLATION" executing address $0.." . Seems to be caused somewhere around the "TMapViewerEngine.Destroy" execution. Any idea what might cause this?

Second the program does not terminate properly on the small machine (1 GB RAM). Exceution has to be killed in the IDE ("Halt"), or by the Windows Task Manager.

Third the program seems to eat RAM. "Process Explorer" (from the Sysinternal Suite) reports increasing RAM size, each time new tiles are loaded for display. Is this behavior normal? Or limited to a certain point?

Any help is greatly appreciated.
TinyPortal © 2005-2018