Platforms to show: All Mac Windows Linux Cross-Platform
/MacFrameworks/MapKit/MapKit Test
Required plugins for this example: MBS MacBase Plugin, MBS MacFrameworks Plugin, MBS MacCG Plugin, MBS MacCF Plugin, MBS Main Plugin
You find this example project in your Plugins Download as a Xojo project file within the examples folder: /MacFrameworks/MapKit/MapKit Test
This example is the version from Tue, 11th Nov 2019.
Project "MapKit Test.xojo_binary_project"
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:
The items on this page are in the following plugins: MBS MacFrameworks Plugin.