Numbers書類上に記載した緯度経度情報を取得して、動的に作成したウィンドウの地図上にプロット表示するAppleScriptです。
実行には、「場所名」「緯度」「経度」がワンセットとなったNumbers書類をNumbersでオープンした状態で、本AppleScriptをスクリプトエディタ上でオープンし、Control-Command-Rを実行します。
ひととおり地図上の指定位置へのピンの作成が終わると、普通に地図アプリなどと同様に拡大や縮小、3D表示、マップ表示、航空写真表示などを切り替えてブラウズすることが可能です。
AppleScript名:Numbersから緯度経度情報を取得して地図にプロット v3(プログレスバー+セグメント) |
— Created 2017-12-20 by Takaaki Naganoya — 2017 Piyomaru Software use AppleScript version "2.5" use scripting additions use framework "Foundation" use framework "AppKit" use framework "MapKit" use framework "CoreLocation" use bPlus : script "BridgePlus" –https://www.macosxautomation.com/applescript/apps/Script_Libs.html#BridgePlus property NSView : a reference to current application’s NSView property NSScreen : a reference to current application’s NSScreen property NSButton : a reference to current application’s NSButton property SMSForder : a reference to current application’s SMSForder property NSWindow : a reference to current application’s NSWindow property MKMapView : a reference to current application’s MKMapView property MKMapTypeHybrid : a reference to current application’s MKMapTypeHybrid property MKPointAnnotation : a reference to current application’s MKPointAnnotation property MKMapTypeSatellite : a reference to current application’s MKMapTypeSatellite property NSWindowController : a reference to current application’s NSWindowController property NSTitledWindowMask : a reference to current application’s NSTitledWindowMask property MKMapTypeStandard : a reference to current application’s MKMapTypeStandard property NSSegmentedControl : a reference to current application’s NSSegmentedControl property NSNormalWindowLevel : a reference to current application’s NSNormalWindowLevel property NSBackingStoreBuffered : a reference to current application’s NSBackingStoreBuffered property NSSegmentStyleTexturedRounded : a reference to current application’s NSSegmentStyleTexturedRounded property windisp : false property selSeg : 0 property aMapView : missing value –データを取得する set locList to getDataFromNumbersDoc() of me set aWidth to 800 set aHeight to 600 set segTitleList to {"Map", "Satellite", "Satellite + Map"} set tableTitle to retCurNumbersDocsTableName() of me dispMapView(aWidth, aHeight, tableTitle, "OK", 180, locList, segTitleList) of me on dispMapView(aWidth as integer, aHeight as integer, aTitle as text, aButtonMSG as text, timeOutSecs as number, locList, segTitleList) –Check If this script runs in foreground if not (current application’s NSThread’s isMainThread()) as boolean then error "This script must be run from the main thread (Command-Control-R in Script Editor)." end if set selSeg to 0 set (my windisp) to true –NSViewをつくる set aNSView to NSView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aHeight, aWidth)) aNSView’s setNeedsDisplay:true set aWin to makeWinWithView(aNSView, aWidth, aHeight, aTitle, 1.0) set wController to NSWindowController’s alloc() wController’s initWithWindow:aWin wController’s showWindow:me aWin’s makeKeyAndOrderFront:me –Windowを表示状態に –Progress Barをつくる set aPBar to current application’s NSProgressIndicator’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 40, aWidth, 40)) aPBar’s setMaxValue:(length of locList) aPBar’s setMinValue:1 aPBar’s setIndeterminate:false aPBar’s setControlSize:(current application’s NSProgressIndicatorPreferredLargeThickness) aPBar’s setDoubleValue:(1.0 as real) aNSView’s addSubview:aPBar –MKMapViewをつくる set aMapView to MKMapView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 40, aWidth, aHeight – 40)) aMapView’s setMapType:(current application’s MKMapTypeStandard) aMapView’s setZoomEnabled:true aMapView’s setScrollEnabled:true aMapView’s setPitchEnabled:true aMapView’s setRotateEnabled:false aMapView’s setShowsCompass:true aMapView’s setShowsZoomControls:true aMapView’s setShowsScale:true aMapView’s setShowsUserLocation:true aMapView’s setDelegate:me –MapにPinを追加 set aCount to 1 repeat with i in locList (aPBar’s setDoubleValue:(aCount as real)) –Update Progress Bar copy i to {tmpAdr, tmpLat, tmpLong} set aLocation to current application’s CLLocationCoordinate2DMake(tmpLat, tmpLong) set anAnnotation to MKPointAnnotation’s alloc()’s init() (anAnnotation’s setCoordinate:aLocation) (anAnnotation’s setTitle:tmpAdr) (aMapView’s addAnnotation:anAnnotation) set aCount to aCount + 1 end repeat aPBar’s removeFromSuperview() –Remove Progress Bar –Segmented Controlをつくる set aSeg to makeSegmentedControl(segTitleList, aWidth, aHeight) of me aNSView’s addSubview:aSeg –MapViewをWindow上に表示 copy middle item of locList to {tmpAdr, tmpLat, tmpLong} set aLocation to current application’s CLLocationCoordinate2DMake(tmpLat, tmpLong) aMapView’s setCenterCoordinate:aLocation zoomLevel:7 animated:false aNSView’s addSubview:aMapView –Buttonをつくる set bButton to (NSButton’s alloc()’s initWithFrame:(current application’s NSMakeRect(aWidth – 100, 0, 100, 40))) bButton’s setTitle:aButtonMSG bButton’s setButtonType:(current application’s NSMomentaryLightButton) bButton’s setBezelStyle:(current application’s NSRoundedBezelStyle) bButton’s setKeyEquivalent:(return) bButton’s setTarget:me bButton’s setAction:("clicked:") aNSView’s addSubview:bButton aWin’s makeFirstResponder:aMapView set aCount to timeOutSecs * 10 –timeout seconds * 10 repeat aCount times if (my windisp) = false then exit repeat end if delay 0.1 end repeat my closeWin:aWin end dispMapView –Button Clicked Event Handler on clicked:aSender set (my windisp) to false end clicked: –make Window for Input on makeWinWithView(aView, aWinWidth, aWinHeight, aTitle, alphaV) set aScreen to NSScreen’s mainScreen() set aFrame to {{0, 0}, {aWinWidth, aWinHeight}} set aBacking to NSTitledWindowMask set aDefer to NSBackingStoreBuffered — Window set aWin to NSWindow’s alloc() (aWin’s initWithContentRect:aFrame styleMask:aBacking backing:aDefer defer:false screen:aScreen) aWin’s setTitle:aTitle aWin’s setDelegate:me aWin’s setDisplaysWhenScreenProfileChanges:true aWin’s setHasShadow:true aWin’s setIgnoresMouseEvents:false aWin’s setLevel:(NSNormalWindowLevel) aWin’s setOpaque:false aWin’s setAlphaValue:alphaV –append aWin’s setReleasedWhenClosed:true aWin’s |center|() aWin’s makeKeyAndOrderFront:(me) — Set Custom View aWin’s setContentView:aView return aWin end makeWinWithView –close win on closeWin:aWindow repeat with n from 10 to 1 by -1 (aWindow’s setAlphaValue:n / 10) delay 0.02 end repeat aWindow’s |close|() end closeWin: on makeSegmentedControl(titleList, aWidth, aHeight) set aLen to length of titleList set aSeg to NSSegmentedControl’s alloc()’s init() aSeg’s setSegmentCount:aLen set aCount to 0 repeat with i in titleList set j to contents of i (aSeg’s setLabel:j forSegment:aCount) set aCount to aCount + 1 end repeat aSeg’s setTranslatesAutoresizingMaskIntoConstraints:false aSeg’s setSegmentStyle:(NSSegmentStyleTexturedRounded) aSeg’s setFrame:(current application’s NSMakeRect(10, 5, 260, 30)) aSeg’s setTrackingMode:0 aSeg’s setTarget:me aSeg’s setAction:"clickedSeg:" aSeg’s setSelectedSegment:0 return aSeg end makeSegmentedControl –Numbersでオープン中の書類の選択中のシートの表1からデータを取得して2D Listに on getDataFromNumbersDoc() load framework tell application "Numbers" if (count every document) = 0 then return false tell front document if (count every sheet) = 0 then return false tell active sheet tell table 1 set colCount to column count set rowCount to row count set headerCount to header row count set footerCount to footer row count set dList to value of every cell of cell range end tell end tell end tell end tell –Convert 1D List to 2D List set bList to (SMSForder’s subarraysFrom:dList groupedBy:colCount |error|:(missing value)) as list set sItem to 1 + headerCount set eItem to rowCount – footerCount set cList to items sItem thru eItem of bList return cList end getDataFromNumbersDoc on retCurNumbersDocsTableName() tell application "Numbers" tell front document tell active sheet tell table 1 return name end tell end tell end tell end tell end retCurNumbersDocsTableName on clickedSeg:aSender set aSel to aSender’s selectedSegment() set selSeg to (aSel + 1) set mapList to {MKMapTypeStandard, MKMapTypeSatellite, MKMapTypeHybrid} set curMap to contents of item selSeg of mapList aMapView’s setMapType:(curMap) end clickedSeg: |