Umwandeln Adresse in Koordinaten

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 25 Antworten in diesem Thema. Der letzte Beitrag () ist von -Franky-.

    Umwandeln Adresse in Koordinaten

    Hallo,

    ich versuche das hier zu benutzen: MapLocationFinder.FindLocationsAsync()
    Aber den Namespace Windows.Services.Maps, wo diese Klasse drin sein soll, scheint es nicht im normalen Windows zu geben. (Das scheint speziellere Anwendung zu finden)
    Beim Googlen wird man auch auf den Namespace XPlat.Services.Maps verwiesen, da fehlt aber die Klasse dann wieder obwohl sie auch dort eigentlich drin sein sollte

    Weiß jemand wofür das eigentlich ist? Oder gibt es da noch Alternativen? Kann man das auch auf nem PC machen?
    Ich gehe davon aus, dass ich damit Adressen in Koordinaten umwandeln kann. So stehts zumindest im Beispiel.

    Viele Grüße

    Haudruferzappeltnoch schrieb:

    Aber den Namespace Windows.Services.Maps, wo diese Klasse drin sein soll, scheint es nicht im normalen Windows zu geben.

    Doch die gibt es. Das ist eine Klasse für UWP-Apps. -> github.com/tpn/winsdk-10/blob/…t/windows.services.maps.h
    Teilweise lassen sich auch UWP-Interfaces/WinRT-Interfaces direkt in Desktop-Apps verwenden ohne ein NuGet-Package dazu installieren zu müssen. Das das ohne NuGet-Package funktioniert, hab ich ja mit ein paar Beispielen im Forum "Sourcecode-Austausch" gezeigt (PDF Seiten zu Bitmap / OCR / FaceDetection / Audio- und Video-Konverter). Aktuell hangel ich mich am Windows.Graphics.Capture.GraphicsCapturePicker entlang (siehe Screenshot).

    Edit: Jo, wird noch mit VB6 programmiert wie man Screenshot sehen kann. Und wenn das da läuft, dann bastel ich auch eine .Net Version.
    Bilder
    • CapturePicker.png

      98,03 kB, 962×674, 60 mal angesehen
    Mfg -Franky-

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „-Franky-“ ()

    Hi

    Installieren musst Du eigentlich nichts. Es sei denn Du möchtest dieses Nuget Paket installieren. Ab Windows 10 ist ja vieles bereits OnBoard. Also auch diese Maps-Geschichte. Da müsste es auch eine UWP-App Maps in Win10 geben.

    Der Link zeigt Dir die WinRT-Header Datei mit den enthaltenen Klassen und Interfaces. Ich schau mir die Headerfiles an und fang an zu programmieren. Solange das alles auf COM basiert, ist das easy (für mich). Wie Du das an meinen Beispielen sehen kannst, gibt es keine zusätzlichen Verweise oder Nuget-Pakete die ich nutze. Ich verwende nur die Infos, die ich aus diesen Headerdateien lesen kann. Also ja, selbst programmieren. So richtig schön Oldschool. ;)

    Manche Sachen unter Win10, die man auch im eigenen Code nutzen kann, erfordern allerdings ein vorhandenes MS-Konto und evtl. andere Freigaben damit diese Dienste überhaupt funktionieren. Da könnte Maps auch drunter fallen (Standortfreigabe usw) da wahrscheinlich die ganze Berechnung usw garnicht lokal stattfindet, sondern online auf irgendeinem MS-Server. Aber das lässt sich ja herausfinden ob es auch ohne geht.
    Mfg -Franky-

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „-Franky-“ ()

    Hi

    Den Namespace wirst du wahrscheinlich nur auswählen können, wenn Du eine UWP-App erstellst (ungetestet) oder nach groben überfliegen von @ISliceUrPanties Links, wenn Du das Nuget Paket in einem C# .NET 6 Projekt installierst. Kann aber auch sein das ich beim grob überfliegen der Links auch übersehen habe das das auch für VB .NetFx geht.

    Wenn es für VB .NetFx nicht geht, dann musst alles selbst programmieren. Headerfile lesen und die Klassen/COM-Interfaces selbst aktivieren (APIs RoGetActivationFactory / RoActivateInstance) und entsprechend verwenden bzw per QueryInterface weitere COM-Interfaces erstellen usw. Was anderes machen meine VB .NetFx Beispiele, die WinRT verwenden, auch nicht. Ich erspare mir aber für jedes Interface eine Klasse anzulegen und auch noch in entsprechenden Namespaces zu packen.

    OnBord heißt bei mir das entsprechende Klassen und COM-Interfaces in Windows registriert und in irgendwelchen DLLs vergraben sind. Schau mal in deinen System32 Ordner. Da findest Du zb ganz viele Windows.xxx.xxx.DLLs. Das sind zB WinRT-DLLs. Diese exportieren evtl. ein paar Funktionen. Diese enthalten aber auch entsprechende Klassen und COM-Interfaces die Du in VB .NetFx so nicht über einen Verweis erreichst/geladen bekommst.

    Das angesprochene Nuget Paket wird ein Wrapper sein der wiederum entsprechende Klassen/Namespaces enthält die auch nichts anderes machen als die WinRT Klassen/COM-Interfaces über die Ro-APIs zu aktivieren und deren Funktionen zur Verfügung zu stellen. Durch die Angabe des Klassennamens und IID, schauen die Ro-APIs in der Registry nach, in welcher DLL entsprechende Klassen/Interfaces enthalten sind und laden diese.
    Mfg -Franky-

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „-Franky-“ ()

    Ok dieses Headerfile ist der Link den du mir genannt hast. Was wird denn da für ein Code benutzt? Weil lesen kann ich das leider nicht.

    Also als Beispiel du hast so ein Headerfile zu deinem OCR Programm und hast damit die OCR-Klasse erstellt?

    -Franky- schrieb:

    Diese enthalten aber auch entsprechende Klassen und COM-Interfaces die Du in VB .NetFx so nicht über einen Verweis erreichst/geladen bekommst.
    Das hört sich an als könnte man die trotzdem benutzen, wie macht man das denn?

    Soweit ich das von @ISliceUrPanties gelesen habe muss ich da NET 6 verwenden. "make sure the TargetFramework element in the project file is assigned to a Windows 10-specific moniker, such as net6.0-windows10.0.19041.0" Das wäre was ich daraus jetzt verstanden hätte.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    Hi

    Die Headerfiles lese ich wie ganz normale C++ Headerfiles und schauen auch so ähnlich aus. Ist aber wahrscheinlich kein C++.

    Jupp. Für das OCR Beispiel habe ich in diese Headerdatei geschaut: github.com/tpn/winsdk-10/blob/…winrt/windows.media.ocr.h Da kommen aber noch weitere Headerdateien dazu.

    Du kannst Dir auch das Win10 SDK installieren. Dann hast Du die ganzen Headerfiles auf deiner Platte und musst nicht online nach den Headerfiles ausschau halten.

    Klar kannst du das in VB NetFx verwenden. Da ich gerade nur über Handy schreibe und nicht am PC sitze, ist das ein wenig schwierig diese Headerfiles am Handy anzuzeigen. Vllt erkennst Du ja anhand meiner Beispiele wie ich entsprechende Klassen und Interfaces lade und verwende.

    Vllt komme ich am Montag dazu dir zu sagen wo da, für das was Du möchtest, der Einstieg ist.
    Mfg -Franky-
    Hi

    Achso, schau mal in deinen System32 Ordner ob es da eine Windows.Services.Maps.dll gibt. Ich weiß das ich diese zb auf Arbeit nicht habe weil wir da diverse Apps per PowerShell-Script deinstallieren. Vllt komme ich morgen mal dazu auf meinen privaten Laptop zu schauen. Wobei ich da auch so einige UWP-Apps deinstalliert habe die ich nicht benötige.

    Edit: Nope, diese DLL gibt es auch nicht auf meinem Laptop. Aber ich habe noch die UWP-App "Karten" und die funktioniert auch. Also sind der Namespace / die Klassen / die Interfaces in einer anderen DLL vergraben.
    Mfg -Franky-

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „-Franky-“ ()

    Hi Auf die schnelle.

    Einstieg: Wenn Du in dem Headerfile mal nach "FindLocationsAsync" suchst, dann landest Du beim Interface IMapLocationFinderStatics. Wenn Du dann nach "IMapLocationFinderStatics" suchst, findest Du ganz unten die Klasse "Windows.Services.Maps.MapLocationFinder". So. Du brauchst jetzt noch die IID vom Interface IMapLocationFinderStatics. Die siehst Du wenn Du wieder nach "FindLocationsAsync" suchst -> MIDL_INTERFACE("318ADB5D-1C5D-4F35-A2DF-AACA94959517") oder Du gehst zur Seite magnumdb.com und suchst dort nach der IID vom Interface IMapLocationFinderStatics -> magnumdb.com/search?q=IID_IMapLocationFinderStatics.

    Du hast jetzt 2 wichtige Parameter. Den Klassennamen und die IID von dem Interface, in der sich die Funktion FindLocationsAsync befindet. Wenn Du Dir nochmal ganz unten im Headerfile die Klasse anschaust, dann steht da:
    * RuntimeClass contains static methods.
    * Static Methods exist on the Windows.Services.Maps.IMapLocationFinderStatics2 interface starting with version 3.0 of the Windows.Foundation.UniversalApiContract API contract
    * Static Methods exist on the Windows.Services.Maps.IMapLocationFinderStatics interface starting with version 1.0 of the Windows.Foundation.UniversalApiContract API contract

    Static Methods aktivierst Du per API RoGetActivationFactory. Andere Interfaces, die auch in einer Klasse enthalten sein können, können entweder direkt per API RoActivateInstance aktiviert werden oder werden aus den xxxStatics Interfaces erstellt. Von IMapLocationFinderStatics zu IMapLocationFinderStatics2 kommst Du per QueryInterface mit der IID_IMapLocationFinderStatics2.

    Also Du rufst meine Hilfsfunktion GetActivationFactory mit dem KLassennamen "Windows.Services.Maps.MapLocationFinder" und der IID_IMapLocationFinderStatics auf und erhältst so einen Pointer auf das Interface IMapLocationFinderStatics. Mit dem Pointer wird dann entsprechend weiter gearbeitet, das kannst Dir ja aus meinen Beispielen abschauen wie ich da vorgehe. FindLocationsAsync benötigt 2 [IN] Parameter. Ein HSTRING (wird per API WindowsCreateString von einen String erzeugt, wichtig: selbst erzeugte HSTRING müssen per dann auch wieder per API WindowsDeleteString gelöscht werden), Optional einen Pointer auf ein Interface IGeopoint (befindet sich dann wohl im Headerfile Windows.Devices.
    Geolocation.h, für uns erstmal uninteressant, also Intptr.Zero übergeben). Zurück bekommst dann ein Pointer auf ein Interface IMapLocationFinderResult.

    [retval, out] */__RPC__deref_out_opt __FIAsyncOperation_1_Windows__CServices__CMaps__CMapLocationFinderResult * * result
    Lese ich dann so: result ist ein Pointer auf ein Interface IMapLocationFinderResult (das C mach ich zum I). Dieses Interface befindet sich im Headerfile Windows.Services.Maps.h (Windows__CServices__CMaps__) und ist ein Async Interface -> IAsyncOperation. IAsyncOperation implementiert das Interface IAsyncInfo. Meine Hilfsfunktion WaitForAsync arbeitet das entsprechend ab. Ist WaitForAsync = True, kannst Du mit dem Pointer auf IMapLocationFinderResult weiter arbeiten. IID suchen: magnumdb.com/search?q=IID_IMapLocationFinderResult, suche im Headerfile nach "43f1f179-e8cc-45f6-bed2-54ccbf965d9a" und schon bist beim Interface IMapLocationFinderResult. Hier kannst wohl den Status abfragen (Enum MapLocationFinderStatus) und die Locations auslesen.

    [retval, out] */__RPC__deref_out_opt __FIVectorView_1_Windows__CServices__CMaps__CMapLocation * * value -> Pointer auf ein Array (IVectorView) von IMapLocation, im Header Windows.Services.Maps.h. Interface IVectorView suchen (mal über Google gemacht) und dann sieht man das sich das Interface in der Windows.Foundation.Collections.h befindet. Wahrscheinlich hat das Interface die Funktionen GetSize (get_Size, ich lass da das _ gern weg), GetAt usw. GetSize -> Anzahl der Elemente im Array, GetAt mit Index -> Pointer auf ein IMapLocation. usw usw usw. Ich seh schon das es da mit IGeopoint und IMapAddress weiter geht und weiter Infos abgefragt werden können. Jau, da hast was zu tun, da kommt keine langeweile auf. ;)

    Es lohnt sich auch in die MS Doku zu den Interfaces zu schauen. Denn sobald ein Interface IClosable enthält muss dieses mit IClosable.Close (entspricht einem Dispose) geschlossen werden -> meine Hilfsfunktion CloseAndRelease. Ansonsten ganz normales Release.

    Ich seh grad das es auch sowas wie einen Routenplaner und Navigation gibt. Interessant. Schleppt man dann sein Laptop mit ins Auto, dauer Internetverbindung und per USB ein GPS-Empfänger? :D Och nöööö.
    Mfg -Franky-

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „-Franky-“ ()

    Kannst du nochmal zu dem RoGetActivationFactory was sagen? Du sagst "deine Hilfsfunktion", also in dem OCR Beispiel habe ich da

    VB.NET-Quellcode

    1. Private Function GetActivationFactory(ClassName As String,
    2. IID As String,
    3. ByRef pFactory As IntPtr) As Boolean
    4. Dim bolRet As Boolean = False
    5. Dim hString As IntPtr = IntPtr.Zero
    6. If WindowsCreateString(ClassName, ClassName.Length, hString) = S_OK Then
    7. If hString <> IntPtr.Zero Then
    8. If RoGetActivationFactory(hString, New Guid(IID), pFactory) = S_OK Then bolRet = True
    9. WindowsDeleteString(hString)
    10. End If
    11. End If
    12. Return bolRet
    13. End Function
    Das ist die Hilfsfunktion, die du meinst?

    Was ist dann das hier eigentlich

    VB.NET-Quellcode

    1. <DllImport("Combase.dll", EntryPoint:="RoGetActivationFactory")>
    2. <PreserveSig> Private Shared Function RoGetActivationFactory(<[In]> activatableClassId As IntPtr,
    3. <[In], MarshalAs(UnmanagedType.LPStruct)> riid As Guid,
    4. <Out> ByRef factory As IntPtr) As Integer
    5. End Function
    Ist das die "Aktivierung" die du meinst?
    --------------------------------------------------------------------------------------------------------
    Theoretisch habe ich ja alles außer die Klasse MapLocationFinder, also so ein GeoPoint den kann ich schon aufrufen in meinem Code, weil da ein Verweis zum entsprechenden Namespace existiert.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    Hi

    GetActivationFactory ist meine Hilfsfunktion die zum einen aus einem String ein HSTRING macht (WindowsCreateString) und das ganze mit der IID der API RoGetActivationFactory übergibt, die Dir dann den Pointer auf ein COM-Interface zurück gibt und der HSTRING wieder gelöscht wird. Damit aktiviere ich die Static-Interfaces aus einer Klasse.

    Theoretisch betrachtet hast du dann ein COM-Interface aus einer Klasse, die deine gewünschte Funktion enthält. Nicht mehr und nicht weniger. Der Funktion kannst Du einen GeoPoint übergeben (Optional). Den musst dann entsprechend marshallen weil Windows-Intern wird mit Pointern gearbeitet und nicht mit Klassen oder Namespaces.

    Ansonsten würde ich komplett auf irgendwelche zusätzlichen Verweise verzichten und ausschließlich mit Pointern arbeiten wenn ich mit COM-Interfaces arbeite.

    Edit: Schau mal was ich da noch gefunden habe: MapLocationFinder Class
    Your Universal Windows app must be authenticated before it can use the MapControl and map services in the Windows.Services.Maps namespace. To authenticate your app, you must specify a maps authentication key.

    Wie bereits angedeutet, könnte es sein das das ganze nicht funktioniert wenn... Ist so ähnlich wie wenn man die Google-APIs nutzen möchte um deren Maps- und andere Services zu nutzen. Da brauchst auch einen API-Key für.

    Achso. Wenn ich von einem Pointer auf ein COM-Interface spreche, dann meine ich eigentlich einen Pointer auf die VTable eines Interfaces. Die VTable enthält dann die Pointer auf die eigentlichen Funktionen des Interfaces.
    Mfg -Franky-

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „-Franky-“ ()

    Also ich habe jetzt so einen Key.

    Im Beispiel steht zum Hinzufügen nur das:
    MapService.ServiceToken = "abcdef-abcdefghijklmno"
    Wo muss das denn genau hin? Weil die MapService Klasse ist ja schon im Services.Maps Namespace. Das heißt das kann ich nicht in meine Anwendung schreiben, weil ja der Namespace noch fehlt.
    Hi

    Das kann ich Dir im Moment gar nicht sagen wo das hingehört. Hab mich ja selbst mit den Maps noch gar nicht beschäfftigt. Irgendwo muss es ja ein Property ServiceToken geben. Musst Du mal die Headerfiles durchsuchen.

    Edit: Findes Du ebenfalls in der windows.services.maps.h -> Interface IMapServiceStatics -> put_ServiceToken/get_ServiceToken
    Mfg -Franky-
    Ich werde mich später an diesen Headerfiles versuchen, ich finde das ganz interessant.

    Ich habe jetzt die Windows SDK installiert und den Ansatz von @ISliceUrPanties probiert. Leider war das auch ohne Erfolg.
    Kann ich das in einer Windows Forms App nicht verwenden?

    Ist das überhaupt eine "Desktop App"? Was heißt ein Projekt wurde mit MSIX gepackt?
    Was sind Projekte die auf Windows 10 Version 1803 oder höher ausgerichtet sind? Wo legt man das fest?

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()