Hallo Access Freunde,
mit folgendem Code stelle ich einen Fundpunkt aus meiner Datenbank in OpenStreetMap dar:
Private Sub ShowOpenStreetMap_Click()
Dim geobreite As Double
Dim geolaenge As Double
Dim HyperlinkGesamt As String
On Error GoTo Err_ShowOpenStreetMap_Click
geobreite = DezimalGradZahl(Me!A_geobgrad1, Me!A_geobminute1, Me!A_geobsekunde1)
geolaenge = DezimalGradZahl(Me!A_geolgrad1, Me!A_geolminute1, Me!A_geolsekunde1)
If Not (Abs(geobreite) = 0 And Abs(geolaenge) = 0) And Abs(geobreite) < 90 And Abs(geolaenge) < 180 Then
HyperlinkGesamt = OpenStreetMapLink & "?mlat=" & StringKomma2Punkt(CStr(geobreite)) & "&mlon=" &
StringKomma2Punkt(CStr(geolaenge)) & "&zoom=16"
Else
HyperlinkGesamt = OpenStreetMapLink & "?lat=51&lon=11&zoom=6"
End If
Application.FollowHyperlink HyperlinkGesamt, , True
Exit_ShowOpenStreetMap_Click:
Exit Sub
Err_ShowOpenStreetMap_Click:
MsgBox Error$
Resume Exit_ShowOpenStreetMap_Click
End Sub
Wie müsste der Code aussehen, wenn ich mehrere Fundpunkte z. B. aus einer Abfrage heraus gleichzeitig in OpenStreetMap darstellen möchte?
LG
Frank
Zitat von: Mykis am November 19, 2022, 14:07:48Wie müsste der Code aussehen, wenn ich mehrere Fundpunkte z. B. aus einer Abfrage heraus gleichzeitig in OpenStreetMap darstellen möchte?
Ich glaube, mehrere Punkte kannst du mit einem simplen Link und URL-Parametern nicht darstellen. Dafür wirst du JavaScript und eine passende Bibliothek einsetzen müssen. Es gibt zahlreiche Beispiel für den Einsatz verschiedener Mapping-Bibliotheken, z.B. hier Beispiele für OpenStreeMap mit der OpenLayers- und der Leaflet-Bibliothek (http://harrywood.co.uk/maps/examples/).
Außerdem könntest du die mal die Downloads zu dem Landkarten-Vortrag von Thomas Pfoch bei der AEK22 (http://donkarl.com/AEK) anschauen.
Hallo PhilS,
vielen Dank.
ZitatIch glaube, mehrere Punkte kannst du mit einem simplen Link und URL-Parametern nicht darstellen.
Über einen simplen Link mit URL Parameter geht das natürlich nicht. Ich hatte die Vorstellung, dass eine Routine im VBA die Wiederholung der einzelnen Geodaten aus einer Abfrage auch mehrere Markierungen in der OpenStreetMap erzeugen könnte. Ich selbst bin dazu nicht in der Lage. Es wäre ja möglich, dass sich schon mal jemand mit dieser Problematik aus einer Access Datenbank heraus beschäftigt hat.
LG
Frank
Zitat von: Mykis am November 19, 2022, 22:04:08Es wäre ja möglich, dass sich schon mal jemand mit dieser Problematik aus einer Access Datenbank heraus beschäftigt hat.
Meinen Hinweis auf den Vortrag bei der AEK22 hast du gesehen? - Dort hat sich jemand sehr intensiv mit dieser Problematik beschäftigt.
Den Vortrag AEK 22 habe ich mir angesehen. Dort werden aber nur eingebundene Karten als Kacheln dargestellt. Die Firma picoware ist sicher in der Lage, ein Modul zu programmieren, was mehrere Fundpunkte auf OpenstreetMap anzeigen kann. Sie vertreibt ja auch interaktive Karten, die direkt in Access eingebunden sind.
Als ehrenamtlicher Pilzberater, der das Kartierungsprogramm unseres Vereins betreut, sind solche Ausgaben für eine professionelle Hilfe nicht machbar.
LG
Frank
Zitat von: PhilS am November 19, 2022, 16:19:59Dafür wirst du JavaScript und eine passende Bibliothek einsetzen müssen. Es gibt zahlreiche Beispiel für den Einsatz verschiedener Mapping-Bibliotheken
@Mykis, dieser Hinweis scheint dir ja nicht weiterzuhelfen. Kannst du mal kurz schreiben, woran es scheitert?
Ich überlege einen längeren Beitrag für meine Website oder YouTube zu erstellen, die dieses Thema behandelt (keine Garantie, kein Termin!). Dafür wüsste ich gern, worin die Schwierigkeiten bei dem obigen, konkreten Ansatz liegen.
Zitat..... dieser Hinweis scheint dir ja nicht weiterzuhelfen. Kannst du mal kurz schreiben, woran es scheitert?
Es scheitert einfach an meinen Fähigkeiten. Auch wenn ich aufgrund meiner bisherigen Aktivitäten hier als "Access Profi" bezeichnet werde, trifft das wirklich nicht zu. Mit JavaScript habe ich noch nie gearbeitet.
LG
Frank
Hallo PhiLS,
als ersten kleinen Schritt wollte ich mal OpenStreetMap in mein Formular einbauen und den einen Fundpunt dort anzeigen lassen. Leider kommt da keine Karte.
Mit GoogleMaps funktioniert es!
(https://www.tomentella.de/Pages/1.png)
Mein Steuerelement: ="http://www.openstreetmap.org?mlat=" & [ZielLat] & "&mlon=" & [ZielLon] & "&zoom=16"
LG
Frank
Glückauf :) Frank,
im Formular hast du (vermutlich) das Webbrowser-Steuerelement, welches auf dem alten Internetexplorer basiert. Dieser ist (standardmäßig) nicht in der Lage die OSM-Seite korrekt anzuzeigen.
Evtl. kann man da noch am Kompatibilitätsmodus schrauben, aber das ist nmM. eine Sackgasse.
Auch wirst du deinem Ziel mehrere Standorte anzuzeigen so nicht näher kommen.
Ein einfach gangbarer Weg wäre aus Access eine Internetseite (Datei mit HTML-Code) zu generieren und diese Datei mit einem aktuellen Browser anzuzeigen.
Hallo Steffen,
vielen Dank für deine Antwort.
[zitat]im Formular hast du (vermutlich) das Webbrowser-Steuerelement, welches auf dem alten Internetexplorer basiert. Dieser ist (standardmäßig) nicht in der Lage die OSM-Seite korrekt anzuzeigen.[/zitat]
Ich arbeite unter Windows 11/Access 2010/Browser MS Edge bzw. Firefox, jeweils die neueste Version. Also könnte es nur an Access 2010 liegen? GoogleMaps geht allerdings in diesem Formular!
[zitat]Ein einfach gangbarer Weg wäre aus Access eine Internetseite (Datei mit HTML-Code) zu generieren und diese Datei mit einem aktuellen Browser anzuzeigen.[/zitat]
Diese Internetseite müsste da ja georeferenziert sein!? Dein "einfacher gangbarer Weg" ist für mich noch ein Buch mit sieben Siegeln. :)
LG
Frank
Hallo Frank
Ich habe hier ein Beispiel für OpenStreetMap. Vielleicht hilft das weiter.
Hallo,
ZitatIch arbeite unter Windows 11/Access 2010/Browser MS Edge bzw. Firefox, jeweils die neueste Version.
Das Steuerelement
in deinem Formular ist kein Edge und kein FF sondern ein (alter) IE.
ZitatGoogleMaps geht allerdings in diesem Formular!
Ja viele Internetseiten funktionieren auch noch im alten IE, aber OSM halt nicht.
ZitatDiese Internetseite müsste da ja georeferenziert sein!?
Nein es ist ganz normaler HTML/Javascriptcode.
Folgender Beispielcode in eine Textdatei, welche du anschließend in pilze.html umbennenst und per Doppelklick startest:
<html>
<head>
<title>Leaflet marker array example</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css" integrity="sha256-kLaT2GOSpHechhsozzB+flnD+zUyjE2LlfWPgU04xyI=" crossorigin="" />
<script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js" integrity="sha256-WBkoXOwTeyKclOHuWtc+i2uENFpDZ9YPdf5Hf+D7ewM=" crossorigin=""></script>
<script language="javascript">
function init() {
var map = new L.Map('map');
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="http://openstreetmap.org">OpenStreetMap</a> contributors',
maxZoom: 18
}).addTo(map);
map.attributionControl.setPrefix(''); // Don't show the 'Powered by Leaflet' text.
var mitte = new L.LatLng(51.5056,-0.1213);
map.setView(mitte, 15);
// Define an array. This could be done in a seperate js file.
// This tidy formatted section could even be generated by a server-side script
// or fetched seperately as a jsonp request.
var markers = [
[ -0.1244324, 51.5006728, "Big Ben" ],
[ -0.119623, 51.503308, "London Eye" ],
[ -0.1279688, 51.5077286, "Nelson's Column<br><a href=\"https://en.wikipedia.org/wiki/Nelson's_Column\">wp</a>" ]
];
//Loop through the markers array
for (var i=0; i<markers.length; i++) {
var lon = markers[i][0];
var lat = markers[i][1];
var popupText = markers[i][2];
var markerLocation = new L.LatLng(lat, lon);
var marker = new L.Marker(markerLocation);
map.addLayer(marker);
marker.bindPopup(popupText);
}
}
</script>
</head>
<body onLoad="javascript:init();">
<div id="map" style="height: 100%"></div>
</body>
</html>Hier müssen letztendlich nur die Koordinaten und Texte durch deine Werte ersetzt werden.
Im Ganzen ca. 20-30 Zeilen VBA-Code.
Danke, Steffen!
mit dem Ersetzen der Geodaten in der html werde ich mich nun mal beschäftigen. Die Daten sollen ja aus einen Abfrage kommen. Wahrscheinlich brauche ich da nochmal Hilfe.
Das Problem mit der Anzeige im Access Fenster habe ich gelöst. Folgender Eintrag muss in die Registry, dann klappt es wunderbar:
HKCU\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION" /v MSACCESS.EXE /t REG_DWORD /d 11000
LG
Frank
Hallo Steffen,
ZitatHier müssen letztendlich nur die Koordinaten und Texte durch deine Werte ersetzt werden.
Hier schon mal mein erster Stolperstein: Wenn ich in der HTML andere Lat/lon Werte eingebe, entstehen keine neuen Marker.
LG
Frank
Zitat von: Mykis am November 26, 2022, 10:35:36Wenn ich in der HTML andere Lat/lon Werte eingebe, entstehen keine neuen Marker.
Es wäre hilfreich, wenn du mindestens den Code-Teil mit den neuen Werten hier ergänzen würdest.
Sorry, hier mal der Codeteil des js mit zwei weiteren lat/lon, wo in Deutschland zwei Marker entstehen müssten.
<script language="javascript">
function init() {
var map = new L.Map('map');
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="http://openstreetmap.org">OpenStreetMap</a> contributors',
maxZoom: 18
}).addTo(map);
map.attributionControl.setPrefix(''); // Don't show the 'Powered by Leaflet' text.
var mitte = new L.LatLng(51.5056,-0.1213);
map.setView(mitte, 15);
// Define an array. This could be done in a seperate js file.
// This tidy formatted section could even be generated by a server-side script
// or fetched seperately as a jsonp request.
var markers = [
[ -0.1244324, 51.5006728, "Big Ben" ],
[ -0.119623, 51.503308, "London Eye" ],
[ 12,77631, 50,85144 ],
[ 12,76040, 50,85620 ],
];
//Loop through the markers array
for (var i=0; i<markers.length; i++) {
var lon = markers[i][0];
var lat = markers[i][1];
var popupText = markers[i][2];
var markerLocation = new L.LatLng(lat, lon);
var marker = new L.Marker(markerLocation);
map.addLayer(marker);
marker.bindPopup(popupText);
}
}
</script>
Zitat von: Mykis am November 26, 2022, 11:13:27 [ 12,77631, 50,85144 ],
[ 12,76040, 50,85620 ],
Die Geokoordinaten müssen mit US-Zahlenformat eingetragen werden; d.h. mit dem Punkt als Dezimaltrennzeichen.
PS: Außerdem bin ich nicht sicher, ob die Beschreibungen zu dem Positionen optional sind. Evtl. musst du mindestens einen leeren String ("") angeben.
Danke, kleine Ursache, große Wirkung. :)
Die Beschreibungen zu dem Positionen sind optional und die brauche auch nicht.
Da werde ich nun mal meinen Javascrpt-Anfängerkurs weitermachen.
Lg
Frank
Hallo
@steffen0815,
ZitatHier müssen letztendlich nur die Koordinaten und Texte durch deine Werte ersetzt werden.
Im Ganzen ca. 20-30 Zeilen VBA-Code.
Das Access Browser-Fenster in meinem Fundpunkteformular ist jetzt so vorbereitet:
Option Compare Database
Private WithEvents CWeb As SHDocVw.WebBrowser
Option Explicit
Private Sub Form_Load()
Me!Webbrowser76.Object.Navigate2 "about:blank"
Set CWeb = Me!Webbrowser76.Object
End Sub
Private Sub Fundpunkte_Click()
Dim oDoc As Object
Dim sHTML As String
CWeb.Navigate2 "about:blank"
WaitForReady
Set oDoc = CWeb.Document
sHTML = "..............."
oDoc.write sHTML
'Dim urlMap As String
'urlMap = "C:\Users\Frank\Desktop\pilze.html"
'Me!Webbrowser76.Object.Silent = True
'Me!Webbrowser76.Object.Navigate2 urlMap
End Sub
Private Sub WaitForReady()
Do
DoEvents
Loop Until CWeb.ReadyState >= READYSTATE_INTERACTIVE
End Sub
Mein momentanes Problem ist den Code aus pilze.html (z.Zt. 2 feste Fundpunkte, die dann späterdurch Abfragewerte ersetzt werden sollen) in den obigen Code in den Zeilen sHTML einzubauen, damit diese Seite im Fenster gezeigt wird. Dazu habe ich im Netz keine Anleitung gefunden.
<html>
<head>
<title>Leaflet marker array example</title>
// <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.3/dist/leaflet.css" integrity="sha256-kLaT2GOSpHechhsozzB+flnD+zUyjE2LlfWPgU04xyI=" crossorigin="" />
// <script src="https://unpkg.com/leaflet@1.9.3/dist/leaflet.js" integrity="sha256-WBkoXOwTeyKclOHuWtc+i2uENFpDZ9YPdf5Hf+D7ewM=" crossorigin=""></script>
<script language="javascript">
function init() {
var map = new L.Map('map');
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="http://openstreetmap.org">OpenStreetMap</a> contributors',
maxZoom: 18
}).addTo(map);
map.attributionControl.setPrefix(''); // Don't show the 'Powered by Leaflet' text.
var mitte = new L.LatLng( 50.85144, 12.85144, 6 );
map.setView(mitte, 6);
// Define an array. This could be done in a seperate js file.
// This tidy formatted section could even be generated by a server-side script
// or fetched seperately as a jsonp request.
var markers = [
[ 12.77631, 50.85144 ],
[ 12.76041, 50.85621 ],
];
//Loop through the markers array
for (var i=0; i<markers.length; i++) {
var lon = markers[i][0];
var lat = markers[i][1];
var markerLocation = new L.LatLng(lat, lon);
var marker = new L.Marker(markerLocation);
map.addLayer(marker);
}
}
</script>
</head>
<body onLoad="javascript:init();"><div id="map" style="height: 100%"></div>
</body>
</html>
Schönen ersten Advent
Frank
Hallo,
viele Ziele führe zum Ziel.
In der "Grundcode" (pilze.html) würde ich das Koordinatenarray und die Mittelpunktkoordinate durch einen "Kenner" ersetzen var markers = [
#KENNKoo#
];und diesen per sHTML = Replace(sHTML, "#KENNKoo#", DeineKoordinaten) tauschen.
Je nachdem wie "transportabel" deine DB sein soll würde ich den Grundcode in einer Datei <muster.html> oder in einer Tabelle (Memofeld) speichern.
Eine Datei in einen Variable einlesen ist recht einfach
Function fncDatei2String(DatNam As String)
Const ForReading = 1
Dim objFSO As Object, objStream As Object
On Error GoTo Fehler
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objStream = objFSO.OpenTextFile(DatNam, ForReading)
fncDatei2String = objStream.ReadAll
objStream.Close
Exit Function
Fehler:
msgbox Err.Number & ": " & Err.Description
End Function
Ein Tabellenfeld (MEMO) auslesen am Einfachsten per DLookUp()
Hallo Steffen,
deinen dankbaren Hinweisen folgend,habe ich den html code in ein Memofeld der Tabelle "Grundcode" in die Spalte "Inhalt" kopiert. Erstmal noch mit einem Koordinatenpaar, um zu testen. Ich erhalte aber nur eine leere Seite im Access Browserfenster.
Private Sub Form_Load()
Me!Webbrowser76.Object.Navigate2 "about:blank"
Set CWeb = Me!Webbrowser76.Object
Me!Webbrowser76.Object.Silent = True
End Sub
Private Sub Fundpunkte_Click()
Dim oDoc As Object
Dim sHTML As String
Dim strX As String
strX = DLookup("Inhalt", "Grundcode")
CWeb.Navigate2 "about:blank"
WaitForReady
Set oDoc = CWeb.Document
sHTML = strX
'sHTML = Replace(sHTML, "#KENNKoo#", "[12.77631, 50.85144]")
oDoc.write sHTML
End Sub
LG
Frank
Wenn ich den Code irgend einer anderen HTML (ohne Javascript) in das Memofeld eingebe, funktioniert die Anzeige dieser Page im Browserfeld.
Hier mal eine Verknüpfung zu meiner Test.accdb
LG
Frank
https://www.tomentella.de/Pages/Fundpunkte.zip (https://www.tomentella.de/Pages/Fundpunkte.zip)
Hallo,
ZitatEvtl. kann man da noch am Kompatibilitätsmodus schrauben, aber das ist nmM. eine Sackgasse.
Ich denke auch hier ist wieder der alte Internetexplorer das Problem.
Setz mal den stummen Modus auf false
Me!Webbrowser76.Object.Silent = Falseund du wirst vermutlich eine Fehlermeldung erhalten (deine DB habe ich mir noch nicht angesehen).
Auch hier könnte man wieder zaubern, aber der alte IE ist und bleibt eine Unsicherheit.
[EDIT]
Als Anhang mal ein schnelles Beispiel (dein Beispiel angepasst/erweitert), wie es funktionieren könnte.
29.11.22: Neue Beispieldatenbank mit Koordinaten direkt aus der Tabelle
Hallo Steffen,
vielen Dank für deine Bemühungen. Selbst hätte ich das nicht so hinbekommen. Meine erste "dumme" Frage dazu wäre, dass der Code für die Karte 4 Koordinatenpaare und die Karte aber 5 Punkte zeigt!?
arrKoo(0, 0) = 12.042: arrKoo(0, 1) = 50.012
arrKoo(1, 0) = 12.012: arrKoo(1, 1) = 50.023
arrKoo(2, 0) = 12.032: arrKoo(2, 1) = 50.045
arrKoo(3, 0) = 12.014: arrKoo(3, 1) = 50.055
LG
Frank
Hallo Steffen,
der Fehler lag im Grundcode/Fuss, da wurde durch folgende Zeile ein zusätzlicher Marker für die Mitte gesetzt.
"markers.addMarker(new OpenLayers.Marker(lonLatMitte));"
LG
Frank
Hallo Steffen,
nochmals vielen Dank für deine professionelle Hilfe. Die Karte enstspricht jetzt perfekt meinen Vorstellungen.
LG
Frank