Archive for the 'MKMapView' Category

2017/12/26 Numbersから緯度経度情報を取得して地図にプロット v3

Numbersでオープン中の書類の現在選択中のシートにある表の内容を読み取って、MKMapViewの地図にピンで位置をプロットして表示するAppleScriptです。

実行にはShane StanleyのAppleScriptライブラリ「BridgePlus」のインストールを必要とします。

実行時にはNumbersで「ピン名称」「緯度」「経度」のデータをオープンしておく必要があります。

→ sample data (Numbers)

実行にはスクリプトエディタ上でControlーCommandーRを実行してください。

前バージョンからは、

  Pinデータ作成時にプログレスバーを表示
  地図種別切り替え

を追加してみました。680箇所の位置データをプロットさせてみたら10秒程度かかったので、プログレスバーを表示させたらいい感じでした。

map40_resized.png

map41_resized.png

map42_resized.png

map43_resized.png

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”
–http://piyocast.com/as/archives/5065

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:

★Click Here to Open This Script 

2017/12/23 Numbersから緯度経度情報を取得して地図にプロット

Numbersでオープン中の書類の現在選択中のシートにある表の内容を読み取って、MKMapViewの地図にピンで位置をプロットして表示するAppleScriptです。

map23_resized.png

スクリーンショット例は「戦場の絆」の導入されているゲームセンターの住所から緯度・経度情報を求めて本Scriptで地図表示させたものです。

Numbersの表示中のシート中の表からデータを読み取るわけですが、「ピンのタイトル」「緯度(Latitude)」「経度(Longitude)」でデータが構成されている必要があります。読み取り時にはとくにNumbers上でセルを選択しておく必要はありません。

→ sample data (Numbers)

map20_resized.png

実行にはShane StanleyのAppleScriptライブラリ「BridgePlus」のインストールを必要とします。

map21_resized.png

Numbersで「ピンのタイトル」「緯度(Latitude)」「経度(Longitude)」がセットになったデータをオープンした状態で、スクリプトエディタ上でControl-Command-Rと操作すると実行できます。

map30_resized.png

Script Menuに入れて実行することも可能ですが、その場合にはボタンをクリックさせてウィンドウをクローズすることができません。

map22_resized.png

AppleScript名:Numbersから緯度経度情報を取得して地図にプロット
– 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”
–http://piyocast.com/as/archives/5051

property |NSURL| : a reference to current application’s |NSURL|
property NSData : a reference to current application’s NSData
property NSView : a reference to current application’s NSView
property NSString : a reference to current application’s NSString
property NSScreen : a reference to current application’s NSScreen
property NSButton : a reference to current application’s NSButton
property NSWindow : a reference to current application’s NSWindow
property MKMapView : a reference to current application’s MKMapView
property NSURLRequest : a reference to current application’s NSURLRequest
property NSURLConnection : a reference to current application’s NSURLConnection
property NSJSONSerialization : a reference to current application’s NSJSONSerialization
property NSWindowController : a reference to current application’s NSWindowController
property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding

property windisp : false

–データを取得する
set locList to getDataFromNumbersDoc() of me

set aWidth to 800
set aHeight to 500

dispMapView(aWidth, aHeight, “Result”, “OK”, 180, locList) of me

on dispMapView(aWidth as integer, aHeight as integer, aTitle as text, aButtonMSG as text, timeOutSecs as number, locList)
  
  
–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 (my windisp) to true
  
  
–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を追加
  
repeat with i in locList
    copy i to {tmpAdr, tmpLat, tmpLong}
    
    
set aLocation to current application’s CLLocationCoordinate2DMake(tmpLat, tmpLong)
    
set anAnnotation to current application’s MKPointAnnotation’s alloc()’s init()
    (
anAnnotation’s setCoordinate:aLocation)
    (
anAnnotation’s setTitle:tmpAdr)
    (
aMapView’s addAnnotation:anAnnotation)
  end repeat
  
  
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
  
  
–Buttonをつくる
  
set bButton to (NSButton’s alloc()’s initWithFrame:(current application’s NSMakeRect(aWidth / 4, 0, aWidth / 2, 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:”)
  
  
–SplitViewをつくる
  
set aSplitV to NSView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aHeight, aWidth))
  
aSplitV’s addSubview:aMapView
  
aSplitV’s addSubview:bButton
  
aSplitV’s setNeedsDisplay:true
  
  
set aWin to makeWinWithView(aSplitV, aWidth, aHeight, aTitle, 1.0)
  
  
  
set wController to NSWindowController’s alloc()
  
wController’s initWithWindow:aWin
  
aWin’s makeFirstResponder:aMapView
  
wController’s showWindow:me
  
  
aWin’s makeKeyAndOrderFront:me
  
  
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 current application’s NSTitledWindowMask
  
set aDefer to current application’s 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:(current application’s 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:

–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 (current application’s 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

★Click Here to Open This Script 

2017/12/21 指定IPアドレスの情報を取得してMKMapViewで表示 v3

指定のIPアドレスの情報をfreegeoip.netのREST APIを呼び出して取得し、緯度、経度情報からMKMapViewで地図を表示するAppleScriptの改良版です。

map10.png

map11.png

map12.png

フロントエンドプロセスで実行する必要があるため、スクリプトエディタ上でControl+Command-Rで実行します。

指定位置をピンで表示していますが、とくにピンを落とすアニメーションは不要と考えて省略しています。ほかにも、不要なアニメーションを省略しています。

AppleScriptのワークフローで地図を表示させる必然性は高くありません。指定場所から半径500m以内に存在する施設を検索するなどの計算を行なって、結果を表示させるぐらいでしょうか。ただ、スマートフォンではないので大量に位置座標の計算や表示を行なってもネットワークやCPUがへこたれないため、いくらでも計算できます。

インタラクティブに地図を表示するMLMapViewよりも、地図画像を取得するMKMapSnapshotterの方が合っているかもしれません。ただ、MKMapSnapshotterの呼び出しはBlocks構文が必要なようなので(=AppleScriptから呼べないので)、ちょっと手をつけていません。

AppleScript名:指定IPアドレスの情報を取得してMKMapViewで表示 v3
– Created 2015-12-11 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.5″
use scripting additions
use framework “Foundation”
use framework “AppKit”
use framework “MapKit”
use framework “CoreLocation”
–http://piyocast.com/as/archives/5050

property |NSURL| : a reference to current application’s |NSURL|
property NSData : a reference to current application’s NSData
property NSView : a reference to current application’s NSView
property NSString : a reference to current application’s NSString
property NSScreen : a reference to current application’s NSScreen
property NSButton : a reference to current application’s NSButton
property NSWindow : a reference to current application’s NSWindow
property MKMapView : a reference to current application’s MKMapView
property NSURLRequest : a reference to current application’s NSURLRequest
property NSURLConnection : a reference to current application’s NSURLConnection
property NSJSONSerialization : a reference to current application’s NSJSONSerialization
property NSWindowController : a reference to current application’s NSWindowController
property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding

property windisp : false

set nRes to hasInternetConnection() of me
if nRes = false then
  display dialog “No Internet Connection….” buttons {“OK”} default button 1 with icon 0
  
return
end if

set aClip to the clipboard
set anIP to text returned of (display dialog “Input IP address to find its location” default answer aClip)

–Check If this script runs in foreground
if not (current application’s NSThread’s isMainThread()) as boolean then
  display alert “This script must be run from the main thread (Command-Control-R in Script Editor).” buttons {“Cancel”} as critical
  
error number -128
end if

set windisp to false
set aInfo to getIPAddressInfoFreeGeoIP(anIP) of me

if aInfo = missing value then
  display dialog “Network Error”
  
return
end if

set aLong to (longitude of (aInfo as record)) as real
set aLat to (latitude of (aInfo as record)) as real
set aZip to zip_code of (aInfo as record)

set aWidth to 450
set aHeight to 500

set aButtonMSG to “OK”

dispMapView(aWidth, aHeight, “MKMapView TEST v3″, aButtonMSG, 180, aLat, aLong) of me

on dispMapView(aWidth as integer, aHeight as integer, aTitle as text, aButtonMSG as text, timeOutSecs as number, aLat, aLong)
  
  
set (my windisp) to true
  
  
–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:true
  
aMapView’s setShowsCompass:true
  
aMapView’s setShowsZoomControls:true
  
aMapView’s setShowsScale:true
  
aMapView’s setShowsUserLocation:true
  
  
set aLocation to current application’s CLLocationCoordinate2DMake(aLat, aLong)
  
aMapView’s setCenterCoordinate:aLocation zoomLevel:10 animated:false
  
aMapView’s setDelegate:me
  
  
–MapにPinを追加
  
set anAnnotation to current application’s MKPointAnnotation’s alloc()’s init()
  
anAnnotation’s setCoordinate:aLocation
  
anAnnotation’s setTitle:aTitle
  
aMapView’s addAnnotation:anAnnotation
  
  
–Buttonをつくる
  
set bButton to (NSButton’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, 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:”)
  
  
–SplitViewをつくる
  
set aSplitV to NSView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aHeight, aWidth))
  
aSplitV’s addSubview:aMapView
  
aSplitV’s addSubview:bButton
  
aSplitV’s setNeedsDisplay:true
  
  
set aWin to makeWinWithView(aSplitV, aWidth, aHeight, aTitle, 1.0)
  
  
  
set wController to NSWindowController’s alloc()
  
wController’s initWithWindow:aWin
  
aWin’s makeFirstResponder:aMapView
  
wController’s showWindow:me
  
  
aWin’s makeKeyAndOrderFront:me
  
  
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 current application’s NSTitledWindowMask
  
set aDefer to current application’s 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:(current application’s 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:

–http://freegeoip.net
on getIPAddressInfoFreeGeoIP(IPAddress)
  try
    with timeout of 10 seconds
      set link to “http://freegeoip.net/json/” & IPAddress
      
set theURL to |NSURL|’s URLWithString:link
      
set jsonData to NSData’s dataWithContentsOfURL:theURL
      
set aJsonDict to (NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value))
      
return aJsonDict
    end timeout
  on error
    return missing value
  end try
end getIPAddressInfoFreeGeoIP

–Internet Connection Check
on hasInternetConnection()
  set aURL to |NSURL|’s alloc()’s initWithString:“http://www.google.com”
  
set aReq to NSURLRequest’s alloc()’s initWithURL:aURL cachePolicy:(current application’s NSURLRequestReloadIgnoringLocalCacheData) timeoutInterval:5.0
  
set urlRes to (NSURLConnection’s sendSynchronousRequest:aReq returningResponse:(missing value) |error|:(missing value))
  
if urlRes = missing value then
    return false
  else
    return true
  end if
end hasInternetConnection

★Click Here to Open This Script 

2017/12/20 指定IPアドレスの情報を取得してMKMapViewで表示

指定のIPアドレスの情報をIP-APIのREST APIを呼び出して取得し、緯度、経度情報からMKMapViewで地図を表示するAppleScriptです。

map1.png

map2.png

map3.png

map4.png

map5.png

前バージョンではshellのcurlコマンドでREST APIを呼び出していましたが、Shane Stanleyからツッコミが入って書き換えました。

フロントエンドプロセスで実行する必要があるため、スクリプトエディタ上でControl+Command-Rで実行します。ASObjC Explorer 4やScript Debugger上では表示できない可能性があります(あと、アプレットに書き出して実行するとエラーに、、、、)。

ずいぶん昔に作りかけて放置していたScriptに機能追加と修正を加えたものだったので、不思議な処理を行なっている部分がありました。初回掲載時からこれを修正しました。

AppleScript名:指定IPアドレスの情報を取得してMKMapViewで表示
– Created 2015-12-11 by Takaaki Naganoya
– 2015 Piyomaru Software
use AppleScript version “2.5″
use scripting additions
use framework “Foundation”
use framework “AppKit”
use framework “MapKit”
use framework “CoreLocation”
use framework “Carbon”
–http://piyocast.com/as/archives/5041

property |NSURL| : a reference to current application’s |NSURL|
property NSData : a reference to current application’s NSData
property NSString : a reference to current application’s NSString
property NSScreen : a reference to current application’s NSScreen
property NSButton : a reference to current application’s NSButton
property NSWindow : a reference to current application’s NSWindow
property NSSplitView : a reference to current application’s NSSplitView
property MKMapView : a reference to current application’s MKMapView
property NSJSONSerialization : a reference to current application’s NSJSONSerialization
property NSWindowController : a reference to current application’s NSWindowController
property NSUTF8StringEncoding : a reference to current application’s NSUTF8StringEncoding

property windisp : false

set anIP to “175.139.227.170″

set aInfo to getIPAddressInfo(anIP) of me

if aInfo = missing value then
  display dialog “Network Error”
  
return
end if

set aLong to (lon of (aInfo as record)) as real
set aLat to (lat of (aInfo as record)) as real

set aWidth to 450
set aHeight to 300

set aTitle to “MKMapTypeStandard”
set aButtonMSG to “OK”

if current application’s AEInteractWithUser(-1, missing value, missing value) is not equal to 0 then return

dispMapView(aWidth, aHeight, aTitle, aButtonMSG, 180, aLat, aLong) of me

on dispMapView(aWidth as integer, aHeight as integer, aTitle as text, aButtonMSG as text, timeOutSecs as number, aLat, aLong)
  
  
set (my windisp) to true
  
  
–MKMapViewをつくる
  
set aMapView to MKMapView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight))
  
aMapView’s setMapType:(current application’s MKMapTypeStandard)
  
  
–MKMapTypeStandard –Works, First run may not display map texts
  
–MKMapTypeHybrid –Works
  
–MKMapTypeSatellite–Works
  
–MKMapTypeSatelliteFlyover–Works
  
–MKMapTypeHybridFlyover–Works
  
–MKMapTypeMutedStandard–Not Works (Error)
  
  
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:false
  
  
set aLocation to current application’s CLLocationCoordinate2DMake(aLat, aLong)
  
aMapView’s setCenterCoordinate:aLocation zoomLevel:17 animated:false
  
aMapView’s setDelegate:me
  
  
  
–Buttonをつくる
  
set bButton to (NSButton’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, 40)))
  
bButton’s setTitle:aButtonMSG
  
bButton’s setKeyEquivalent:(return)
  
bButton’s setTarget:me
  
bButton’s setAction:(“clicked:”)
  
  
–SplitViewをつくる
  
set aSplitV to NSSplitView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aHeight, aWidth))
  
aSplitV’s setVertical:false
  
  
aSplitV’s addSubview:aMapView
  
aSplitV’s addSubview:bButton
  
aSplitV’s setNeedsDisplay:true
  
  
set aWin to makeWinWithView(aSplitV, aWidth, aHeight, aTitle, 1.0)
  
  
set wController to NSWindowController’s alloc()
  
wController’s initWithWindow:aWin
  
aWin’s makeFirstResponder:aMapView
  
wController’s showWindow:me
  
  
aWin’s makeKeyAndOrderFront:me
  
  
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 current application’s NSTitledWindowMask –NSBorderlessWindowMask
  
set aDefer to current application’s 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:(current application’s NSModalPanelWindowLevel) – original : 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:

–http://ip-api.com/docs/
on getIPAddressInfo(IPAddress)
  set link to “http://ip-api.com/json/” & IPAddress & “?fields=country,city,isp,org,as,mobile,proxy,message,lat,lon”
  
set theURL to |NSURL|’s URLWithString:link
  
set jsonData to NSData’s dataWithContentsOfURL:theURL
  
set aJsonDict to (NSJSONSerialization’s JSONObjectWithData:jsonData options:0 |error|:(missing value))
  
return aJsonDict
end getIPAddressInfo

★Click Here to Open This Script