Platforms to show: All Mac Windows Linux Cross-Platform

/Mac64bit/MapKit/MapKit Test
Required plugins for this example: MBS MacBase Plugin, MBS MacFrameworks Plugin, MBS Main Plugin, MBS MacCG Plugin, MBS MacCF Plugin
You find this example project in your Plugins Download as a Xojo project file within the examples folder: /Mac64bit/MapKit/MapKit Test
This example is the version from Tue, 11th Nov 2019.
Project "MapKit Test.rbp"
Class App Inherits Application
Const kEditClear = "&Löschen"
Const kFileQuit = "Beenden"
Const kFileQuitShortcut = ""
EventHandler Sub Open() #if TargetMachO and Target64Bit then // okay #else MsgBox "Please run on macOS in 64-bit." #endif End EventHandler
End Class
Class MainWindow Inherits Window
Control Map Inherits MapKitViewControlMBS
ControlInstance Map Inherits MapKitViewControlMBS
EventHandler Sub Open() self.mapview = me.View End EventHandler
EventHandler Sub annotationViewDidChangeDragState(mapView as MKMapViewMBS, annotationView as MKAnnotationViewMBS, newState as integer, oldState as integer) 'dim pinAnnotation as MKAnnotationMBS = annotationView.annotation ' ' 'dim u as integer = UBound(pins) 'for i as integer = 0 to u 'if pins(i) = pinAnnotation then '// found the pin. 'dim circle as MKCircleMBS = circles(i) 'mapView.removeOverlay circle ' 'if newState = MKAnnotationViewMBS.DragStateEnding or newState = MKAnnotationViewMBS.DragStateNone then ' '// create a new circle view 'dim pinCircleRadius as Double = circle.radius ' 'circle = MKCircleMBS.circleWithCenterCoordinate(pinAnnotation.coordinate, pinCircleRadius) 'circles(i) = circle 'mapView.addOverlay circle 'end if 'end if 'next ' End EventHandler
EventHandler Function rendererForOverlay(mapView as MKMapViewMBS, overlay as MKOverlayMBS) As MKOverlayRendererMBS if overlay isa myOverlay then Dim m As New MyOverlayRenderer(overlay) renderers.append m // keep reference to Xojo object! Return m End If If overlay IsA MKCircleMBS Then Dim c As MKCircleMBS = MKCircleMBS(overlay) Dim m As New MKCircleRendererMBS(c) m.FillColor = NSColorMBS.colorWithCalibratedRGB(1,0,0,0.5) renderers.Append m Return m End If End EventHandler
End Control
Control SegmentedControl1 Inherits SegmentedControl
ControlInstance SegmentedControl1 Inherits SegmentedControl
EventHandler Sub Action(itemIndex as integer) setMapType itemIndex End EventHandler
EventHandler Sub Open() me.Items(0).selected = true End EventHandler
End Control
Control addressTextField Inherits TextField
ControlInstance addressTextField Inherits TextField
EventHandler Function KeyDown(Key As String) As Boolean if asc(key) = 3 or asc(key) = 13 then searchAddress Return true end if End EventHandler
End Control
Control SearchButton Inherits PushButton
ControlInstance SearchButton Inherits PushButton
EventHandler Sub Action() searchAddress End EventHandler
End Control
Control PinButton Inherits PushButton
ControlInstance PinButton Inherits PushButton
EventHandler Sub Action() AddPin End EventHandler
End Control
Control pinTitle Inherits TextField
ControlInstance pinTitle Inherits TextField
End Control
Control DemoButton Inherits PushButton
ControlInstance DemoButton Inherits PushButton
EventHandler Sub Action() demo End EventHandler
End Control
Control OverlayButton Inherits PushButton
ControlInstance OverlayButton Inherits PushButton
EventHandler Sub Action() If Keyboard.AsyncOptionKey Then addCustomOverlay Else addCircle End If End EventHandler
End Control
Control Label1 Inherits Label
ControlInstance Label1 Inherits Label
End Control
Control circleRadius Inherits TextField
ControlInstance circleRadius Inherits TextField
End Control
Control UpDownArrows1 Inherits UpDownArrows
ControlInstance UpDownArrows1 Inherits UpDownArrows
EventHandler Sub Down() dim n as integer = cdbl(circleRadius.Text) if n>10 then n = n - 1 circleRadius.Text = cstr(n) end if End EventHandler
EventHandler Sub Up() dim n as integer = cdbl(circleRadius.Text) n = n + 1 circleRadius.Text = cstr(n) End EventHandler
End Control
Control Timer1 Inherits Timer
ControlInstance Timer1 Inherits Timer
EventHandler Sub Action() self.addPinForIndex indexNumber = indexNumber + 1 if indexNumber > UBound(pinNames) then me.Mode = 0 end if End EventHandler
End Control
Control RenderButton Inherits PushButton
ControlInstance RenderButton Inherits PushButton
EventHandler Sub Action() dim options as new MKMapSnapshotOptionsMBS // set some options 'options.mapRect = mapview.visibleRect options.mapType = mapview.mapType options.region = mapview.region options.showsPointsOfInterest = true dim snap as new MKMapSnapshotterMBS(options) snap.Start // just wait for it to finish loading... while snap.Loading app.DoEvents 10 wend // just get picture from snapshot dim n as NSImageMBS = snap.Snapshot.Image if n <> nil then dim f as FolderItem = SpecialFolder.Desktop.Child("test.png") dim b as BinaryStream = BinaryStream.Create(f, true) b.Write n.PNGRepresentation end if End EventHandler
End Control
EventHandler Sub Open() init End EventHandler
Function AblageRemoveallOverlaysPins() As Boolean for each v as Variant in circles mapview.removeOverlay v next for each v as Variant in pins mapview.removeAnnotation v next Return True End Function
Sub AddPin() dim pin as new MKPointAnnotationMBS pin.coordinate = mapView.centerCoordinate pin.title = self.pinTitle.Text pins.Append pin mapView.addAnnotation pin 'dim circle as MKCircleMBS = MKCircleMBS.circleWithCenterCoordinate(mapview.centerCoordinate, CDBl(circleRadius.Text)) 'circles.append circle 'mapView.addOverlay circle // or an polygon? 'dim c as CLLocationCoordinate2DMBS = mapview.centerCoordinate 'dim coords() as CLLocationCoordinate2DMBS ' '// put edge points a few meter away 'const d = 0.01 'dim c1 as new CLLocationCoordinate2DMBS(c.latitude+d, c.longitude+d) 'dim c2 as new CLLocationCoordinate2DMBS(c.latitude+d, c.longitude-d) 'dim c3 as new CLLocationCoordinate2DMBS(c.latitude-d, c.longitude-d) 'dim c4 as new CLLocationCoordinate2DMBS(c.latitude-d, c.longitude+d) ' 'coords.Append c1 'coords.Append c2 'coords.Append c3 'coords.Append c4 ' 'dim poly as MKPolygonMBS = MKPolygonMBS.polygonWithCoordinates(coords) ' 'polygons.Append poly 'mapView.addOverlay poly End Sub
Sub Demo() indexNumber = 0 timer1.Mode = 2 End Sub
Sub SetMapType(n as integer) mapView.mapType = n End Sub
Sub addCircle() dim centerCoordinate as CLLocationCoordinate2DMBS = map.view.centerCoordinate dim radius as integer = cdbl(circleRadius.text) // meter dim circle as MKCircleMBS = MKCircleMBS.circleWithCenterCoordinate(centerCoordinate, radius) mapview.addOverlay circle circle.title = "Hello" circles.Append circle 'dim overlays() as MKOverlayMBS = mapview.overlays 'Break End Sub
Sub addCustomOverlay() Dim centerCoordinate As CLLocationCoordinate2DMBS = map.view.centerCoordinate Dim o As New myOverlay // make it current view big Dim m As MKMapRectMBS = mapview.visibleMapRect o.setBoundingMapRect m o.SetCoordinate centerCoordinate o.canReplaceMapContent = False // overlay, not replace o.title = "MyOverlay" mapview.addOverlay o myOverlays.Append o // keep reference End Sub
Sub addPinForIndex() dim total as integer = pinNames.Ubound+1 dim index as integer = indexNumber dim maxLatOffset as double = 0.01 dim maxLngOffset as double = 0.02 dim name as string = pinNames(indexNumber) dim pin as new MKPointAnnotationMBS const PI = 3.14159265359 dim pinCoord as CLLocationCoordinate2DMBS = mapview.centerCoordinate dim latOffset as double = maxLatOffset * cos(2*PI * (index/total)) dim lngOffset as double = maxLngOffset * sin(2*PI * (index/total)) pinCoord.latitude = pinCoord.latitude + latOffset pinCoord.longitude = pinCoord.longitude + lngOffset pin.coordinate = pinCoord pin.title = name pins.Append pin mapView.addAnnotation pin End Sub
Sub init() pinNames = array("One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve") 'mapview.showsUserLocation = true #if false then // testing some things. // please put breakpoint in events so you see results dim coordinate as new CLLocationCoordinate2DMBS coordinate.latitude = 49.8578255 coordinate.longitude = -97.16531639999999 reverseGeocoder = new MKReverseGeocoderMBS(map, coordinate) reverseGeocoder.start geocoderNoCoord = new MKGeocoderMBS(map, "777 Corydon Ave, Winnipeg MB") geocoderNoCoord.start geocoderCoord = new MKGeocoderMBS(map, "1250 St. James St", coordinate) geocoderCoord.start #endif End Sub
Sub searchAddress() mapView.showAddress addressTextField.text End Sub
Note "Plugins needed"
MacFrameworks Main MacCocoa MacBase MacControls
Property Pins() As MKPointAnnotationMBS
Property circles() As MKCircleMBS
Property coreLocationPins() As Integer
Property geocoderCoord As CLGeocoderMBS
Property geocoderNoCoord As CLGeocoderMBS
Property indexNumber As Integer
Property mapview As MKMapViewMBS
Property menuItem As MyNSMenuItemMBS
Property myOverlays() As myOverlay
Property pinNames() As string
Property polygons() As MKPolygonMBS
Property renderers() As Variant
Property reverseGeocoder As CLGeocoderMBS
End Class
MenuBar MenuBar1
MenuItem FileMenu = "&Ablage"
MenuItem AblageRemoveallOverlaysPins = "Remove all Overlays and Pins"
MenuItem FileQuit = "#App.kFileQuit"
MenuItem EditMenu = "&Bearbeiten"
MenuItem EditUndo = "&Rückgängig"
MenuItem UntitledMenu1 = "-"
MenuItem EditCut = "&Ausschneiden"
MenuItem EditCopy = "&Kopieren"
MenuItem EditPaste = "&Einfügen"
MenuItem EditClear = "#App.kEditClear"
MenuItem UntitledMenu0 = "-"
MenuItem EditSelectAll = "&Alles auswählen"
End MenuBar
Class MyNSMenuItemMBS Inherits NSMenuItemMBS
EventHandler Sub Action() mapView.removeAnnotation MKAnnotationView.annotation End EventHandler
Property MKAnnotationView As MKAnnotationViewMBS
Property mapView As MKMapViewMBS
End Class
Module Module1
Function FindFile(name as string) As FolderItem // Look for file in parent folders from executable on dim parent as FolderItem = app.ExecutableFile.Parent while parent<>Nil dim file as FolderItem = parent.Child(name) if file<>Nil and file.Exists then Return file end if parent = parent.Parent wend End Function
End Module
Class MyOverlayRenderer Inherits MKCustomOverlayRendererMBS
EventHandler Sub DrawMapRect(mapRect as MKMapRectMBS, zoomScale as Double, context as CGContextMBS) // change coordinate system to show just our area Dim rect As CGRectMBS = Self.RectForMapRect(overlay.boundingMapRect) context.ScaleCTM(1.0, -1.0) context.TranslateCTM(0.0, -rect.size.height) // and fill it all in red context.SetRGBFillColor 1,0,0,0.3 context.FillRect rect context.Flush End EventHandler
EventHandler Function canDrawMapRect(mapRect as MKMapRectMBS, zoomScale as Double) As Boolean Return True End EventHandler
End Class
Class myOverlay Inherits MKCustomOverlayMBS
End Class
End Project

See also:

Feedback, Comments & Corrections

The items on this page are in the following plugins: MBS Mac64bit Plugin.

The biggest plugin in space...

MBS FileMaker blog