diff --git a/.github/workflows/api-surface.yml b/.github/workflows/api-surface.yml new file mode 100644 index 0000000..3ac0997 --- /dev/null +++ b/.github/workflows/api-surface.yml @@ -0,0 +1,60 @@ +name: Public API Surface + +# 公開 API サーフェスの凍結ゲート。 +# +# ドライバー層の共通化中、アプリ開発者向け API を変えていないことを機械的に保証する。 +# 意図した変更なら `scripts/api-surface.sh dump ` でベースラインを更新して +# コミットすること。android-sdk の lint.yml の apiCheck ステップに対応する。 +# +# ## CI で見るモジュールが core だけな理由 +# +# プロバイダのビルドにはベンダー SDK が要り、その多くはこのリポジトリに置けない: +# +# - ios-for-here … heresdk/ は .gitignore されている(再配布不可) +# - ios-for-googlemaps … ios-maps-sdk/ も同様 +# - ios-for-mapbox … SPM の取得に Mapbox のトークンが要る +# +# 一方、共通化で実際に動くのは ios-sdk-core であり、凍結を破るならまずここに出る。 +# プロバイダの分は手元で `scripts/api-surface.sh check` を回して確かめること +# (ベースライン自体は 14 モジュールすべてコミットしてある)。 + +on: + pull_request: + types: [opened, reopened, synchronize, ready_for_review] + branches: + - main + workflow_dispatch: + inputs: + modules: + description: "空白区切りのモジュール名。空なら全モジュール。" + required: false + default: "" + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + api-surface: + if: github.event.pull_request.draft == false + runs-on: macos-15 + name: Check public API surface + + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + submodules: recursive + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Check + env: + MODULES: ${{ github.event.inputs.modules }} + run: | + set -euo pipefail + modules="${MODULES:-}" + if [ -z "$modules" ]; then + modules="ios-sdk-core ios-icons" + fi + echo "Running api-surface check for: $modules" + ./scripts/api-surface.sh check $modules diff --git a/.gitignore b/.gitignore index 86f6f32..c06bc4b 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,7 @@ heresdk samples/MapConductorSampleApp/build_sim samples/MapConductorSampleApp/build_device samples/MapConductorSampleApp/UITests +maps-core/ +app1786472922370i267371265/ +samples/MapConductorSampleApp/Resources/mappls.i.conf +samples/MapConductorSampleApp/Resources/mappls.i.olf diff --git a/.gitmodules b/.gitmodules index 719582a..7f4da67 100644 --- a/.gitmodules +++ b/.gitmodules @@ -40,3 +40,24 @@ [submodule "ios-icons"] path = ios-icons url = git@github.com:MapConductor/ios-icons.git +[submodule "ios-for-mappls"] + path = ios-for-mappls + url = git@github.com:MapConductor/ios-for-mappls.git +[submodule "ios-for-openmobilemaps"] + path = ios-for-openmobilemaps + url = git@github.com:MapConductor/ios-for-openmobilemaps.git +[submodule "ios-kml"] + path = ios-kml + url = git@github.com:MapConductor/ios-kml.git +[submodule "ios-for-template"] + path = ios-for-template + url = git@github.com:MapConductor/ios-for-template.git +[submodule "ios-icons-jp"] + path = ios-icons-jp + url = git@github.com:MapConductor/ios-icons-jp.git +[submodule "ios-icons-us"] + path = ios-icons-us + url = git@github.com:MapConductor/ios-icons-us.git +[submodule "ios-icons-weather"] + path = ios-icons-weather + url = git@github.com:MapConductor/ios-icons-weather.git diff --git a/ios-for-arcgis b/ios-for-arcgis index abc1c82..efa73df 160000 --- a/ios-for-arcgis +++ b/ios-for-arcgis @@ -1 +1 @@ -Subproject commit abc1c827ff12593fcda6893fdb555282c805856f +Subproject commit efa73dfb0639eba14a8f1f9a4658bb52f0336c58 diff --git a/ios-for-googlemaps b/ios-for-googlemaps index fade40f..d5ab528 160000 --- a/ios-for-googlemaps +++ b/ios-for-googlemaps @@ -1 +1 @@ -Subproject commit fade40fe94f4d1b89c416222c525c8059b1f7474 +Subproject commit d5ab52879db180213726089e70eeebcf227f9d1a diff --git a/ios-for-here b/ios-for-here index b24d5d3..a674aca 160000 --- a/ios-for-here +++ b/ios-for-here @@ -1 +1 @@ -Subproject commit b24d5d322cfefe9078c8016ddb5662dde28d9d48 +Subproject commit a674aca2404d777a6f3766bb7a494dc96922b75b diff --git a/ios-for-longdo b/ios-for-longdo index a1f75d6..feca680 160000 --- a/ios-for-longdo +++ b/ios-for-longdo @@ -1 +1 @@ -Subproject commit a1f75d6213f5a534056e1f1cf7194290a2f57177 +Subproject commit feca6800dbe28d8fcd1a39ce8c3f6c7480197ac3 diff --git a/ios-for-mapbox b/ios-for-mapbox index cd75fc7..dfe5703 160000 --- a/ios-for-mapbox +++ b/ios-for-mapbox @@ -1 +1 @@ -Subproject commit cd75fc778ed9fd755c85d0f78af14aa8becc72c7 +Subproject commit dfe5703e6299567a87753455248ff86c198ef75b diff --git a/ios-for-mapkit b/ios-for-mapkit index 9db0512..e506bc3 160000 --- a/ios-for-mapkit +++ b/ios-for-mapkit @@ -1 +1 @@ -Subproject commit 9db051286fd16495b68b5d132d9f22ccba811e0a +Subproject commit e506bc3791c79e9d9c800225f7eff6cfea0adf13 diff --git a/ios-for-maplibre b/ios-for-maplibre index 130ce71..7b6fe88 160000 --- a/ios-for-maplibre +++ b/ios-for-maplibre @@ -1 +1 @@ -Subproject commit 130ce7144b460899d52c6bf7efb7a37c8df4656a +Subproject commit 7b6fe88410491bc0e910f0758681b1fcfff0dffa diff --git a/ios-for-mappls b/ios-for-mappls new file mode 160000 index 0000000..ff20ac3 --- /dev/null +++ b/ios-for-mappls @@ -0,0 +1 @@ +Subproject commit ff20ac3ee1655cff250fa930f4f11b09b5df0344 diff --git a/ios-for-maptiler b/ios-for-maptiler index acb652b..b4687af 160000 --- a/ios-for-maptiler +++ b/ios-for-maptiler @@ -1 +1 @@ -Subproject commit acb652b6805276cc0e26a6271f5ee2eb1320729f +Subproject commit b4687af182dad9a3100d5d5b542b05ff1870333d diff --git a/ios-for-openmobilemaps b/ios-for-openmobilemaps new file mode 160000 index 0000000..690c539 --- /dev/null +++ b/ios-for-openmobilemaps @@ -0,0 +1 @@ +Subproject commit 690c53929a4b3647fa525b23d492f25429f82f6e diff --git a/ios-for-template b/ios-for-template new file mode 160000 index 0000000..b5c84b4 --- /dev/null +++ b/ios-for-template @@ -0,0 +1 @@ +Subproject commit b5c84b466adeb1e5c51a02c84d2027b51ba9583e diff --git a/ios-for-tomtom b/ios-for-tomtom index c489532..cd18f38 160000 --- a/ios-for-tomtom +++ b/ios-for-tomtom @@ -1 +1 @@ -Subproject commit c489532ae3fbc00ac340c8f3f013a9416435d9bd +Subproject commit cd18f38406f94213ae882ba785258beefc11d701 diff --git a/ios-geojson-layer b/ios-geojson-layer index fc3e573..7b14932 160000 --- a/ios-geojson-layer +++ b/ios-geojson-layer @@ -1 +1 @@ -Subproject commit fc3e573d1a28136be56cc890838797c530e26ed8 +Subproject commit 7b14932090051fb46f92f50ccc250489ae26c806 diff --git a/ios-heatmap b/ios-heatmap index 1c7b4c0..2166776 160000 --- a/ios-heatmap +++ b/ios-heatmap @@ -1 +1 @@ -Subproject commit 1c7b4c017da5c78887292d5a68dee6333f2b1af8 +Subproject commit 2166776857f2987f3797d045e7b741b194f505c6 diff --git a/ios-icons b/ios-icons index 1d94468..08c0352 160000 --- a/ios-icons +++ b/ios-icons @@ -1 +1 @@ -Subproject commit 1d94468d41e0a55e9264e50cd8e692263da7923d +Subproject commit 08c0352ad6e4d6823e4bcca1aad8b06e7e549baf diff --git a/ios-icons-jp b/ios-icons-jp new file mode 160000 index 0000000..29ad03b --- /dev/null +++ b/ios-icons-jp @@ -0,0 +1 @@ +Subproject commit 29ad03b5b2d88682246cc7fc4de46889c2e0bf5b diff --git a/ios-icons-us b/ios-icons-us new file mode 160000 index 0000000..4edfe21 --- /dev/null +++ b/ios-icons-us @@ -0,0 +1 @@ +Subproject commit 4edfe2177af5d9bec8ccbcec3be2b7ec30299f34 diff --git a/ios-icons-weather b/ios-icons-weather new file mode 160000 index 0000000..4d32345 --- /dev/null +++ b/ios-icons-weather @@ -0,0 +1 @@ +Subproject commit 4d32345b1630ccb947e3eaf58162b99d6688e0a9 diff --git a/ios-kml b/ios-kml new file mode 160000 index 0000000..5f15d6d --- /dev/null +++ b/ios-kml @@ -0,0 +1 @@ +Subproject commit 5f15d6df49fd94ad4ce63f96fdaa75c0a34c3d47 diff --git a/ios-marker-clustering b/ios-marker-clustering index 099462a..99fff8d 160000 --- a/ios-marker-clustering +++ b/ios-marker-clustering @@ -1 +1 @@ -Subproject commit 099462a58ac1079f56d194cdc538f9ee8ef2ae80 +Subproject commit 99fff8dfa6508481c3e52281133e40f6582642b1 diff --git a/ios-sdk-core b/ios-sdk-core index 13d4e50..626600d 160000 --- a/ios-sdk-core +++ b/ios-sdk-core @@ -1 +1 @@ -Subproject commit 13d4e50c914a91f4213a71a9181f3afdc6ea3293 +Subproject commit 626600de8666463d8b273a8629b5fd4ea9b8fb05 diff --git a/samples/MapConductorSampleApp/MapConductorSampleApp.xcodeproj/project.pbxproj b/samples/MapConductorSampleApp/MapConductorSampleApp.xcodeproj/project.pbxproj index 8e6e1a3..b627f39 100644 --- a/samples/MapConductorSampleApp/MapConductorSampleApp.xcodeproj/project.pbxproj +++ b/samples/MapConductorSampleApp/MapConductorSampleApp.xcodeproj/project.pbxproj @@ -16,27 +16,33 @@ 0DB0C1C45CD99B44262FF919 /* FitBoundsMapComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7C4718260907A3770D50458 /* FitBoundsMapComponent.swift */; }; 0E0AB02ADFBFA812B33DBDEC /* VisibleRegionPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EAF083CC1444EF2343A56F7 /* VisibleRegionPage.swift */; }; 0FAC625D001BF5EC93954F1E /* PolylineMapPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BE5BB5D5DB84A8B5E698BB4 /* PolylineMapPage.swift */; }; - 105AB28EF7DC4395C8F056A3 /* MapConductorGeoJSON in Frameworks */ = {isa = PBXBuildFile; productRef = A2893889C0B45F35A8DB0C4B /* MapConductorGeoJSON */; }; + 105AB28EF7DC4395C8F056A3 /* MapConductorForMappls in Frameworks */ = {isa = PBXBuildFile; productRef = 54A8FE0DCEC6B7B6686369C5 /* MapConductorForMappls */; }; + 1091E30A026F66E8E1F46EE4 /* MapplsPerfUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04D303901FC0014E31C66ECD /* MapplsPerfUITests.swift */; }; 10E5AF39816AAE3BD1C04F18 /* GroundImageMapComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 235E67A1859B3CA8F12D37E8 /* GroundImageMapComponent.swift */; }; 129EBE1EB46F88C4E4715E1A /* PostOfficeMapComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C36C321C43614D74792FE49 /* PostOfficeMapComponent.swift */; }; 15BFFF5AEE90E30A1648BF9B /* MapConductorForTomTom in Frameworks */ = {isa = PBXBuildFile; productRef = 7D730C3AFB56BCACB70D7B43 /* MapConductorForTomTom */; }; 17309AC5A47C71C08F82311D /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 313B53E1BB15ED36A24D884A /* ContentView.swift */; }; 17B5F2B2856E7710BC987153 /* UISettingsUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D764AEA50006E42D46EF8E42 /* UISettingsUITests.swift */; }; 18183758DF7D84609BBC70E5 /* StoreMapComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = B129F8127A4F68D7014EF037 /* StoreMapComponent.swift */; }; + 1AAF7237622937ACB3D6450A /* ZIPFoundation in Frameworks */ = {isa = PBXBuildFile; productRef = CC49320174E28DBBB2DA3E3B /* ZIPFoundation */; }; 1AB418776A864E3F7EA42470 /* GroundImageResources.swift in Sources */ = {isa = PBXBuildFile; fileRef = 029F54738EC2590081CA44A8 /* GroundImageResources.swift */; }; 1ECF732832616FF083AC089D /* FlyToPageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 496B5E1E6513458E647DF810 /* FlyToPageViewModel.swift */; }; 21DEE995EF7CDCC705716720 /* MapConductorForLongdo in Frameworks */ = {isa = PBXBuildFile; productRef = 035F4F1283704F98E8E7C663 /* MapConductorForLongdo */; }; 221F14F85019FD4F1742B53A /* PolylineGeodesicPageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D663A887D0AFCDCAF6E4EB7 /* PolylineGeodesicPageViewModel.swift */; }; 239206A33F5255AFF2ED073D /* MapDesignMapPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 536A6FD93067C70FAF6FC8CE /* MapDesignMapPage.swift */; }; 284B63D3105246B496337FDC /* SampleConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 673785C2388A204D53E08EF9 /* SampleConfig.swift */; }; + 2B286E8D0C115213181B1916 /* GeoJSONShotUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34F95A4E1917D6BC3F5C0B82 /* GeoJSONShotUITests.swift */; }; + 2B5770AF7FE2A6CE91E433D4 /* OpenMobileMapsDeviceSweepUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78FB7B1699E13C53108BF653 /* OpenMobileMapsDeviceSweepUITests.swift */; }; 2C31107D1F3D76A5987BC55E /* FlyToMapComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E7322320F385235CECACA81 /* FlyToMapComponent.swift */; }; 32CC3376ECDC8BE23CBE1B46 /* ExampleGeoJSONLayerLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCDDCC99B087D3B1329444A /* ExampleGeoJSONLayerLoader.swift */; }; 346966A6732A7E80DF7BD137 /* PolygonGeodesicPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A543622B3A557165F7C8E10 /* PolygonGeodesicPage.swift */; }; 3494CEED6AE66BCBD33AC145 /* HeatmapPageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B454F900084472843036F8CF /* HeatmapPageViewModel.swift */; }; + 34FB7D29521BEE34749D62EF /* GoogleMaps in Frameworks */ = {isa = PBXBuildFile; productRef = F67792B83660D03AE335EDCD /* GoogleMaps */; }; 385A04B7F95CE23B5F6D9043 /* MapConductorForMapLibre in Frameworks */ = {isa = PBXBuildFile; productRef = DE9E4D481C91003D86901307 /* MapConductorForMapLibre */; }; 393D3040E362D5FAEC3A6DA9 /* HeatmapMapPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2601B9681BC7350C9B999E5 /* HeatmapMapPage.swift */; }; 39BD7B6F805E581E3ECD665D /* ProviderSwitchUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7C711748AE5022E33B5DCC9 /* ProviderSwitchUITests.swift */; }; 3DE14E8C2ED828F123AFEC78 /* HeatmapMapComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C4169D6811740458CDDA8ED /* HeatmapMapComponent.swift */; }; + 3FE6EE1DAC0F59D7B38B2957 /* GeoJSONLayerClickUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3B733B38F2CA606DE5F3C8A2 /* GeoJSONLayerClickUITests.swift */; }; 439ED392E79B767B159AB7A3 /* TiltMapPageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 619427C6B7849A8B98677C4A /* TiltMapPageViewModel.swift */; }; 455F6D8DBBAF522E01199F4A /* California.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05DCD88C1178628A7AD754C3 /* California.swift */; }; 46F5E8DF912419D9D2787CA9 /* PolylineMapComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = E60581AEC1C00F85895B924E /* PolylineMapComponent.swift */; }; @@ -46,8 +52,10 @@ 4F6E927027C5A68A2545D076 /* StyledInfoBubblePage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5828B2F881475BCBDAA22B88 /* StyledInfoBubblePage.swift */; }; 4F81EC1F484EB83629097CD8 /* PolylineClickPageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 635B5B791B73E89988420538 /* PolylineClickPageViewModel.swift */; }; 4FAA3CD1B1C81E78D5EFD48D /* CircleMapComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3413C5C263D93E79F5C6F79 /* CircleMapComponent.swift */; }; + 4FC1432266AE069EF90AB666 /* InfoBubbleCompareUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C904FA9CEC6089ECA225050F /* InfoBubbleCompareUITests.swift */; }; 52D68B68A3B56440B12DF14E /* StartUpPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21BB4D278EEAEE695E62351E /* StartUpPage.swift */; }; 54B5880433557F1FC0C478ED /* PolygonClickPageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8EF3B3111BFBB17B5B1C14F2 /* PolygonClickPageViewModel.swift */; }; + 55FC9049CBE1797978FE5401 /* VisibleRegionPanelUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CEAB1031FDC359DC73B4A8A /* VisibleRegionPanelUITests.swift */; }; 56AAABDA4A3F2F7B7D1BBC8B /* VisibleRegionMapComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47498C58CDEE0E9CF7342A52 /* VisibleRegionMapComponent.swift */; }; 57170F6394EBFE012560B267 /* DemoMapPageScaffold.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1D4F852BF6BEE5EB887B62B /* DemoMapPageScaffold.swift */; }; 58EDB1BF6B43FC714812ED94 /* SpiderfyUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 47EF2B7EE37AC5A382BFA399 /* SpiderfyUITests.swift */; }; @@ -55,32 +63,40 @@ 5D389D96A80C37356179AEE2 /* DemoData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B3C8F4443CED133798AA355 /* DemoData.swift */; }; 5E917641E9ED4BE2C183CB8F /* MarkerBasicMapComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 866556D6922D74C2445D5771 /* MarkerBasicMapComponent.swift */; }; 5FB3C13BA06F1482B4661242 /* GeoJSONLayerMapPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD6BD26E6526A17508DFDE48 /* GeoJSONLayerMapPage.swift */; }; + 6099B1F9204EDECA514773D4 /* InfoBubbleProjectionUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 624CDE3FBAAB41C41BFC73D4 /* InfoBubbleProjectionUITests.swift */; }; 62B38FB816A90530C5E94533 /* Sidebar.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB437D06DC85F2E05CC7F4B3 /* Sidebar.swift */; }; 6318C0A7B64F8D69DE1EEE24 /* FitBoundsMapPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9C0BDC9303996CAFA67CCB72 /* FitBoundsMapPage.swift */; }; 631CDE728E8CCC6DEAAC005C /* CirclePageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0FD3CF585E712FF3B248B0F /* CirclePageViewModel.swift */; }; 634EA220584E00AAFD8022F3 /* MapConductorForGoogleMaps in Frameworks */ = {isa = PBXBuildFile; productRef = 06C1DBF8CB687729DF1C807A /* MapConductorForGoogleMaps */; }; 6BD87DE57C766D0BB384A240 /* CameraRestrictionUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4C6709BFAFDBBE0C3D2504B /* CameraRestrictionUITests.swift */; }; 6D2317AFDDDAEB77C961EC26 /* MapDesignMapComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85C0AB60B489874EBCF704F5 /* MapDesignMapComponent.swift */; }; - 6F54D000AA0F05FEF5CE7E1A /* GoogleMaps in Frameworks */ = {isa = PBXBuildFile; productRef = F67792B83660D03AE335EDCD /* GoogleMaps */; }; + 6F54D000AA0F05FEF5CE7E1A /* MapConductorKML in Frameworks */ = {isa = PBXBuildFile; productRef = D1071D3ED1AFC20892E4FF58 /* MapConductorKML */; }; + 6F6897312AA41B79421BA95C /* CameraSyncArcGISUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A243AD91D8C5452AD848138B /* CameraSyncArcGISUITests.swift */; }; 70FA687400503741ACC26B5E /* RichContentBubblePage.swift in Sources */ = {isa = PBXBuildFile; fileRef = AF2D8AE048398EAB46BC1455 /* RichContentBubblePage.swift */; }; + 723CFFDF4FA4EABD8736B916 /* ClickCascadeUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26C59C5A1489A42CCB3E50B2 /* ClickCascadeUITests.swift */; }; 729F6A4535B02CE619998235 /* StoreMapPageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3DE52221880CD793F1BF0560 /* StoreMapPageViewModel.swift */; }; 72BDA654C664E0E9D9567BB1 /* GroundImagePageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6E16C76A9F0BB857BA08951 /* GroundImagePageViewModel.swift */; }; 754B2C5F6F912D23720FD7A9 /* MapConductorForMapTiler in Frameworks */ = {isa = PBXBuildFile; productRef = DD849FDD6B93F3EDA511B6F1 /* MapConductorForMapTiler */; }; + 75B989F4A6C7BC3F59FE580B /* OpenMobileMapsProjectionUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FE393B5A6AB91D05DD2DF77 /* OpenMobileMapsProjectionUITests.swift */; }; 768036852114CA499289CB4D /* MapDesignPageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39DC859AB185EB39E357FBB2 /* MapDesignPageViewModel.swift */; }; + 77D622AF5E9B3C7036591F63 /* SelectedProviderCarryOverUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B536F77432B5C2C631B09DD1 /* SelectedProviderCarryOverUITests.swift */; }; 78099986D8558396904424B8 /* PostOfficeClusterMapPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9636CBE9C7019A27A04C147 /* PostOfficeClusterMapPage.swift */; }; + 794BB5070971B2EB50A47273 /* NegativeTiltUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 370DD0AE8450C20221B1E3E6 /* NegativeTiltUITests.swift */; }; + 79AB161A992A0CC73CB58A3B /* ClusterZoomUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB97E9FB4272D0D0BFCFC5AD /* ClusterZoomUITests.swift */; }; 7AE25EB485CF3E07C6855302 /* HereHitTestPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32B1FF3E2CC528F12B3F4EAD /* HereHitTestPage.swift */; }; 7B21D76122110C43BD9D414F /* RasterHeaderUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D788830F4469D4610C71A869 /* RasterHeaderUITests.swift */; }; + 7F051E3CC34D18CFF6850A62 /* InfoBubbleProbeUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B318C64E7510720E289F4EF2 /* InfoBubbleProbeUITests.swift */; }; 82F246CF9D7DABFECC0BAB49 /* MultipleBubblesPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D48D5B0D7E2125723C3A9DE /* MultipleBubblesPage.swift */; }; 8703219D862CFC787CC2B082 /* PolylinePageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4C15792FC2A80B01CD49E08 /* PolylinePageViewModel.swift */; }; 876A63315A19B8E0CBBD8FB9 /* StoreInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 596B67D7F433BEA427C799BF /* StoreInfoView.swift */; }; 879866CE6BA654FDBDFE1C3D /* CameraSyncTestPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB0403006AA6C5EB150EABD2 /* CameraSyncTestPage.swift */; }; 886D5CA070732881773AC4BD /* MapConductorCore in Frameworks */ = {isa = PBXBuildFile; productRef = 5F868FD6810605D51D8DE0E0 /* MapConductorCore */; }; - 88D5641422025010188F524B /* MapConductorForHERE in Frameworks */ = {isa = PBXBuildFile; productRef = C8D5A9C0CCED6456B3D81D24 /* MapConductorForHERE */; }; + 88D5641422025010188F524B /* MapConductorHeatmap in Frameworks */ = {isa = PBXBuildFile; productRef = DF824C7DFDFC731E797795D6 /* MapConductorHeatmap */; }; 8B51C0F020F2CFCAAF071D1C /* AnimationMapPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = A58F15C0FEEEB504570717B7 /* AnimationMapPage.swift */; }; 8C557E443C67FAEFAE20FF01 /* StyleReloadPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3FAF468FB00E39057C7B9C96 /* StyleReloadPage.swift */; }; 8DD9330782039E90CD911444 /* UISettingsPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91F0A048B1B580AC5BE76075 /* UISettingsPage.swift */; }; 8F349E5133D9A348DB0F6E85 /* CircleMapPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C5796C83B450E126E53BD5F /* CircleMapPage.swift */; }; - 8F6DF2FC54B36BC96B6C8BE4 /* MapConductorHeatmap in Frameworks */ = {isa = PBXBuildFile; productRef = DF824C7DFDFC731E797795D6 /* MapConductorHeatmap */; }; + 8F6DF2FC54B36BC96B6C8BE4 /* MapConductorForOpenMobileMaps in Frameworks */ = {isa = PBXBuildFile; productRef = 296C0CEC881327C4C3BE65BE /* MapConductorForOpenMobileMaps */; }; 8FB9E5BE76F30E432DCC8174 /* InfoBubbleCustomUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DE6402C500A3CC965F4FEF9 /* InfoBubbleCustomUITests.swift */; }; 973E88576456DA1C7FF2B8AF /* FitBoundsPageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E09E3098A7041DD92F4CDA5D /* FitBoundsPageViewModel.swift */; }; 9BE1985582B254F7E7F9E77F /* MarkerDragUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06F98351A07D308D4D7F2A6E /* MarkerDragUITests.swift */; }; @@ -88,43 +104,54 @@ A902BC97B29AFA4BBBD8310A /* SidebarItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = F23BE35F0F841264AED454DE /* SidebarItem.swift */; }; A92A4D5BB420A460B5E6FED4 /* SampleMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8281BE72BC47056A7E6108BB /* SampleMapView.swift */; }; A955322BEA38C109B9581248 /* StyleReloadUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F98B052B5A45377554CC9C2D /* StyleReloadUITests.swift */; }; + A9C5ACDF37AF9C73F8F32118 /* StyledBubbleUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 77220E1AEF5EA1875A979D02 /* StyledBubbleUITests.swift */; }; AA4893EDEE9ED83024F91791 /* PostOfficeClusterPageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA2AB39A80E3A5C65B944467 /* PostOfficeClusterPageViewModel.swift */; }; - AB3A278E630050C0B69D29C9 /* MapConductorMarkerClustering in Frameworks */ = {isa = PBXBuildFile; productRef = FEB8A11AFC6869DC28064B3D /* MapConductorMarkerClustering */; }; + AB3A278E630050C0B69D29C9 /* MapConductorGeoJSON in Frameworks */ = {isa = PBXBuildFile; productRef = A2893889C0B45F35A8DB0C4B /* MapConductorGeoJSON */; }; B010C23C9F28D88F616EACBC /* ExampleGeoJSONStyler.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5FE164C5622D5ABA920992F /* ExampleGeoJSONStyler.swift */; }; + B0A1D3E58CCB8244F30FBBF4 /* A2DBubbleProbeUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 73E26429303A139633A520F2 /* A2DBubbleProbeUITests.swift */; }; B2B112AA7F88521C3FD10FDD /* HolePolygonUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 08101FE49CA383BD346A656C /* HolePolygonUITests.swift */; }; BD2731DF6E02759221CA5C94 /* CameraSyncTestViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = C251EA117D0D739F43944D94 /* CameraSyncTestViewModel.swift */; }; BE5D7705F2D71DD9DE900C5D /* PostOfficeDataLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2F129A8A5CDCF49717F09F1 /* PostOfficeDataLoader.swift */; }; + BEC3F92921F126CF3DA899C5 /* MapLibreTiltZoomUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8C93487E79A349AC12446EDA /* MapLibreTiltZoomUITests.swift */; }; C4CDD243D337D97B10CFAFBF /* NavigationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B02E9F2ADE08AB6F6A9F0F3 /* NavigationViewModel.swift */; }; + CA785F8851B74FD7C1541F12 /* SelectedProviderStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79A12BB5733A9219AF9BC32E /* SelectedProviderStore.swift */; }; CB49E4C305852E171446DA2E /* HeatmapCameraUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA8730F46EA8AA766554BD56 /* HeatmapCameraUITests.swift */; }; CBAF018856AD8D7727B0904C /* MapConductorForMapbox in Frameworks */ = {isa = PBXBuildFile; productRef = 07F84CB727B4D7BFA9E6BBA9 /* MapConductorForMapbox */; }; CC0E3528375293C416C891DB /* PostOfficePage.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFA7A17FE65561B4737D7AC2 /* PostOfficePage.swift */; }; CFDB054F9C8EA4B05168DF2F /* TokyoPostOffices.swift in Sources */ = {isa = PBXBuildFile; fileRef = DDCE316F0873F733D073DCFB /* TokyoPostOffices.swift */; }; + D136C9B97EE353605F49E3B3 /* OpenMobileMapsSmokeUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D85F0AA9AC34D158C685AB38 /* OpenMobileMapsSmokeUITests.swift */; }; D1683E97E10E09AD57B0C7BE /* TiltMapPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB13F476A2A9A93D09A42D9E /* TiltMapPage.swift */; }; D39229103CD9AC99AB00B6EA /* HolePolygonMapPageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3753C91B977BC9754F803F69 /* HolePolygonMapPageViewModel.swift */; }; D5165A402B239CCB97FD2FE1 /* PolylineClickMapComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372828CAD4DECE4B66C4521D /* PolylineClickMapComponent.swift */; }; D538D79AC73CE6F51FC3C09B /* PostOfficeClusterMapComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71603F4704CD2F7AD581A0D3 /* PostOfficeClusterMapComponent.swift */; }; + D65B9FDDBF8983CFCF3ED2F3 /* MapConductorMarkerClustering in Frameworks */ = {isa = PBXBuildFile; productRef = 22BC8FB0708860F782AD73DF /* MapConductorMarkerClustering */; }; D9EE443DC85D3AE0F4EA3759 /* PostOfficeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AF48ED67015660EDC4DC9ED /* PostOfficeViewModel.swift */; }; DC8F656F22A74CAE5057E238 /* BasicGeoJSONMapPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2E9ACEF15DA4EA6478E15919 /* BasicGeoJSONMapPage.swift */; }; DF8E0172DD76E2A6300EBD6B /* MapConductorForArcGIS in Frameworks */ = {isa = PBXBuildFile; productRef = A9471523A3BF989FE54B2446 /* MapConductorForArcGIS */; }; E08EBDEDB1603FF34CF6F427 /* RasterHeaderPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = F7A9E514E0D709DBB2647B86 /* RasterHeaderPage.swift */; }; E1E2A6D2D99982653D935CDC /* PolylineGeodesicPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C777804F8BD63B74CE6ED7A1 /* PolylineGeodesicPage.swift */; }; E467A41D66C8BF026BD956B7 /* LargeMarkerSwitchUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 539010E48B6C8FEF66E0F280 /* LargeMarkerSwitchUITests.swift */; }; + E50D539EAE73B4B82765B647 /* OpenMobileMapsTilingUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E49B77569013FC71CE767C76 /* OpenMobileMapsTilingUITests.swift */; }; E55D7E7E754923BB4899F1D0 /* PolygonClickMapPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED5E4FF8CA6CC53779C785BE /* PolygonClickMapPage.swift */; }; E57233C3053759A16911AE99 /* MarkerBasicPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C2C941BEF1C5CDE12E6D636E /* MarkerBasicPage.swift */; }; E7096B512D8CCD1AE8F80778 /* MapConductorSampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2FE7D0C3C813CCED5F3853E /* MapConductorSampleApp.swift */; }; E7C4E5761F050CF81C011849 /* PostOfficeInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1D14DA589632894B5B0FBC4 /* PostOfficeInfoView.swift */; }; EB99FD9F2B59CCDF59EFC878 /* AnimationPageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7C78BFE289DDEEABFFDB4D9 /* AnimationPageViewModel.swift */; }; EC1A51ADD6A50B2BE33AE815 /* HolePolygonMapPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBB49746B0EAA41AF2083493 /* HolePolygonMapPage.swift */; }; + ECA4CD8AAA87EBD9F81ED60F /* KMLLayerMapPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 400B3C529916452091CFBFCE /* KMLLayerMapPage.swift */; }; EE24664CA89BC54AB585AD7E /* PolygonMapPageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = E905A2A41F668FBF19BC9519 /* PolygonMapPageViewModel.swift */; }; F0B349FC52422B6A48908AA2 /* SimpleTextBubblePage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16FCD4A32E5D0E85AB2E1024 /* SimpleTextBubblePage.swift */; }; F1984AA149912DDD52D4B8B9 /* RasterLayerMapComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 803C0755788E22BF686AB8DB /* RasterLayerMapComponent.swift */; }; F520A5493A78D7D156153507 /* MapConductorForMapKit in Frameworks */ = {isa = PBXBuildFile; productRef = BCE99CF68028363B1329EC64 /* MapConductorForMapKit */; }; + F563F6AF3F992969EC8A5B17 /* OverlayClickUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D8F401557D0F3F5D9806A6E /* OverlayClickUITests.swift */; }; F8BD7D7E4AD94A01F07C838D /* DemoAppScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0224D133C8AE0A8F51D465BD /* DemoAppScreen.swift */; }; F8D38831B9AFBC8150987736 /* GroundImageMapPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33936F78F0FA083376362231 /* GroundImageMapPage.swift */; }; F9CDC7F7EDE828E44973B26E /* PolygonGeodesicPageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 892A43B49256809B228489B8 /* PolygonGeodesicPageViewModel.swift */; }; FA0747BF013C9E65676F8838 /* VisibleRegionViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC94ABA3629ED355A22E5540 /* VisibleRegionViewModel.swift */; }; + FACC823631EE4D95873171EE /* LongdoClickDiagnosticUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8D1037C9DFD86ADDCF3863DC /* LongdoClickDiagnosticUITests.swift */; }; FC61029EEAAF0FDBD4A5649F /* PolygonMapPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8FDE7D6165092E3147E09F58 /* PolygonMapPage.swift */; }; - FE7DB5E571C7BD47A5729A21 /* ZIPFoundation in Frameworks */ = {isa = PBXBuildFile; productRef = CC49320174E28DBBB2DA3E3B /* ZIPFoundation */; }; + FD16826298AAADD228089FA1 /* VisibleRegionUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AC34113CB0D007B466026CEF /* VisibleRegionUITests.swift */; }; + FE7DB5E571C7BD47A5729A21 /* MapConductorForHERE in Frameworks */ = {isa = PBXBuildFile; productRef = C8D5A9C0CCED6456B3D81D24 /* MapConductorForHERE */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -141,6 +168,7 @@ 01A79993FD9DEFEE0B183916 /* RasterLayerMapPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RasterLayerMapPage.swift; sourceTree = ""; }; 0224D133C8AE0A8F51D465BD /* DemoAppScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoAppScreen.swift; sourceTree = ""; }; 029F54738EC2590081CA44A8 /* GroundImageResources.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroundImageResources.swift; sourceTree = ""; }; + 04D303901FC0014E31C66ECD /* MapplsPerfUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapplsPerfUITests.swift; sourceTree = ""; }; 05DCD88C1178628A7AD754C3 /* California.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = California.swift; sourceTree = ""; }; 06F98351A07D308D4D7F2A6E /* MarkerDragUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MarkerDragUITests.swift; sourceTree = ""; }; 07E56B15B236BE92BD93461D /* Secrets.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Secrets.xcconfig; sourceTree = ""; }; @@ -155,6 +183,7 @@ 21BB4D278EEAEE695E62351E /* StartUpPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StartUpPage.swift; sourceTree = ""; }; 235E67A1859B3CA8F12D37E8 /* GroundImageMapComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroundImageMapComponent.swift; sourceTree = ""; }; 247ED7633D70326148E9523A /* AnimationMapComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimationMapComponent.swift; sourceTree = ""; }; + 26C59C5A1489A42CCB3E50B2 /* ClickCascadeUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClickCascadeUITests.swift; sourceTree = ""; }; 2A543622B3A557165F7C8E10 /* PolygonGeodesicPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PolygonGeodesicPage.swift; sourceTree = ""; }; 2B9266EDD049DA45972FDCE9 /* ios-for-tomtom */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "ios-for-tomtom"; path = "../../ios-for-tomtom"; sourceTree = SOURCE_ROOT; }; 2C36C321C43614D74792FE49 /* PostOfficeMapComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostOfficeMapComponent.swift; sourceTree = ""; }; @@ -164,17 +193,24 @@ 313B53E1BB15ED36A24D884A /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 32B1FF3E2CC528F12B3F4EAD /* HereHitTestPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HereHitTestPage.swift; sourceTree = ""; }; 33936F78F0FA083376362231 /* GroundImageMapPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroundImageMapPage.swift; sourceTree = ""; }; + 34F95A4E1917D6BC3F5C0B82 /* GeoJSONShotUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeoJSONShotUITests.swift; sourceTree = ""; }; + 370DD0AE8450C20221B1E3E6 /* NegativeTiltUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NegativeTiltUITests.swift; sourceTree = ""; }; 372828CAD4DECE4B66C4521D /* PolylineClickMapComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PolylineClickMapComponent.swift; sourceTree = ""; }; 3753C91B977BC9754F803F69 /* HolePolygonMapPageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HolePolygonMapPageViewModel.swift; sourceTree = ""; }; 39DC859AB185EB39E357FBB2 /* MapDesignPageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapDesignPageViewModel.swift; sourceTree = ""; }; + 3B733B38F2CA606DE5F3C8A2 /* GeoJSONLayerClickUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeoJSONLayerClickUITests.swift; sourceTree = ""; }; + 3D8F401557D0F3F5D9806A6E /* OverlayClickUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OverlayClickUITests.swift; sourceTree = ""; }; 3DE52221880CD793F1BF0560 /* StoreMapPageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreMapPageViewModel.swift; sourceTree = ""; }; 3FAF468FB00E39057C7B9C96 /* StyleReloadPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StyleReloadPage.swift; sourceTree = ""; }; + 400B3C529916452091CFBFCE /* KMLLayerMapPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KMLLayerMapPage.swift; sourceTree = ""; }; 47498C58CDEE0E9CF7342A52 /* VisibleRegionMapComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VisibleRegionMapComponent.swift; sourceTree = ""; }; 47EF2B7EE37AC5A382BFA399 /* SpiderfyUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpiderfyUITests.swift; sourceTree = ""; }; 496B5E1E6513458E647DF810 /* FlyToPageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlyToPageViewModel.swift; sourceTree = ""; }; + 4B5FA1B6F9FF315058B30672 /* ios-kml */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "ios-kml"; path = "../../ios-kml"; sourceTree = SOURCE_ROOT; }; 4B8345A4E4E2060505B6AFAF /* FlyToMapPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlyToMapPage.swift; sourceTree = ""; }; 4C4169D6811740458CDDA8ED /* HeatmapMapComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeatmapMapComponent.swift; sourceTree = ""; }; 4DE6402C500A3CC965F4FEF9 /* InfoBubbleCustomUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoBubbleCustomUITests.swift; sourceTree = ""; }; + 4FE393B5A6AB91D05DD2DF77 /* OpenMobileMapsProjectionUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenMobileMapsProjectionUITests.swift; sourceTree = ""; }; 51C699EF9F4BAE6967A14536 /* ios-for-mapkit */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "ios-for-mapkit"; path = "../../ios-for-mapkit"; sourceTree = SOURCE_ROOT; }; 536A6FD93067C70FAF6FC8CE /* MapDesignMapPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapDesignMapPage.swift; sourceTree = ""; }; 539010E48B6C8FEF66E0F280 /* LargeMarkerSwitchUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LargeMarkerSwitchUITests.swift; sourceTree = ""; }; @@ -182,11 +218,19 @@ 5675E69177526509D92883B2 /* ios-for-arcgis */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "ios-for-arcgis"; path = "../../ios-for-arcgis"; sourceTree = SOURCE_ROOT; }; 5828B2F881475BCBDAA22B88 /* StyledInfoBubblePage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StyledInfoBubblePage.swift; sourceTree = ""; }; 596B67D7F433BEA427C799BF /* StoreInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreInfoView.swift; sourceTree = ""; }; + 59A41E8801182242AA851AD7 /* ios-for-openmobilemaps */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "ios-for-openmobilemaps"; path = "../../ios-for-openmobilemaps"; sourceTree = SOURCE_ROOT; }; 619427C6B7849A8B98677C4A /* TiltMapPageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TiltMapPageViewModel.swift; sourceTree = ""; }; + 624CDE3FBAAB41C41BFC73D4 /* InfoBubbleProjectionUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoBubbleProjectionUITests.swift; sourceTree = ""; }; 635B5B791B73E89988420538 /* PolylineClickPageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PolylineClickPageViewModel.swift; sourceTree = ""; }; 673785C2388A204D53E08EF9 /* SampleConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleConfig.swift; sourceTree = ""; }; + 6CEAB1031FDC359DC73B4A8A /* VisibleRegionPanelUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VisibleRegionPanelUITests.swift; sourceTree = ""; }; 6EAF083CC1444EF2343A56F7 /* VisibleRegionPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VisibleRegionPage.swift; sourceTree = ""; }; + 7105347887569C04EFF104DE /* ios-marker-clustering */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "ios-marker-clustering"; path = "../../ios-marker-clustering"; sourceTree = SOURCE_ROOT; }; 71603F4704CD2F7AD581A0D3 /* PostOfficeClusterMapComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostOfficeClusterMapComponent.swift; sourceTree = ""; }; + 73E26429303A139633A520F2 /* A2DBubbleProbeUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = A2DBubbleProbeUITests.swift; sourceTree = ""; }; + 77220E1AEF5EA1875A979D02 /* StyledBubbleUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StyledBubbleUITests.swift; sourceTree = ""; }; + 78FB7B1699E13C53108BF653 /* OpenMobileMapsDeviceSweepUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenMobileMapsDeviceSweepUITests.swift; sourceTree = ""; }; + 79A12BB5733A9219AF9BC32E /* SelectedProviderStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectedProviderStore.swift; sourceTree = ""; }; 7C878252AEEAFC99FEC69A95 /* RasterLayerPageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RasterLayerPageViewModel.swift; sourceTree = ""; }; 803C0755788E22BF686AB8DB /* RasterLayerMapComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RasterLayerMapComponent.swift; sourceTree = ""; }; 8281BE72BC47056A7E6108BB /* SampleMapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleMapView.swift; sourceTree = ""; }; @@ -197,20 +241,26 @@ 8B3C8F4443CED133798AA355 /* DemoData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoData.swift; sourceTree = ""; }; 8BC61F8A5C2B9C5876A0F036 /* ios-for-here */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "ios-for-here"; path = "../../ios-for-here"; sourceTree = SOURCE_ROOT; }; 8C5796C83B450E126E53BD5F /* CircleMapPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleMapPage.swift; sourceTree = ""; }; + 8C93487E79A349AC12446EDA /* MapLibreTiltZoomUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapLibreTiltZoomUITests.swift; sourceTree = ""; }; + 8D1037C9DFD86ADDCF3863DC /* LongdoClickDiagnosticUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LongdoClickDiagnosticUITests.swift; sourceTree = ""; }; 8D48D5B0D7E2125723C3A9DE /* MultipleBubblesPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultipleBubblesPage.swift; sourceTree = ""; }; 8EF3B3111BFBB17B5B1C14F2 /* PolygonClickPageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PolygonClickPageViewModel.swift; sourceTree = ""; }; 8FDE7D6165092E3147E09F58 /* PolygonMapPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PolygonMapPage.swift; sourceTree = ""; }; 91F0A048B1B580AC5BE76075 /* UISettingsPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UISettingsPage.swift; sourceTree = ""; }; 9C0BDC9303996CAFA67CCB72 /* FitBoundsMapPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FitBoundsMapPage.swift; sourceTree = ""; }; + A243AD91D8C5452AD848138B /* CameraSyncArcGISUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraSyncArcGISUITests.swift; sourceTree = ""; }; A58F15C0FEEEB504570717B7 /* AnimationMapPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimationMapPage.swift; sourceTree = ""; }; A7C78BFE289DDEEABFFDB4D9 /* AnimationPageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimationPageViewModel.swift; sourceTree = ""; }; AA8730F46EA8AA766554BD56 /* HeatmapCameraUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeatmapCameraUITests.swift; sourceTree = ""; }; + AC34113CB0D007B466026CEF /* VisibleRegionUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VisibleRegionUITests.swift; sourceTree = ""; }; AD9E7DD79ABF1B72A4B13050 /* ios-sdk-core */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "ios-sdk-core"; path = "../../ios-sdk-core"; sourceTree = SOURCE_ROOT; }; AF2D8AE048398EAB46BC1455 /* RichContentBubblePage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RichContentBubblePage.swift; sourceTree = ""; }; B129F8127A4F68D7014EF037 /* StoreMapComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreMapComponent.swift; sourceTree = ""; }; B2FE7D0C3C813CCED5F3853E /* MapConductorSampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapConductorSampleApp.swift; sourceTree = ""; }; + B318C64E7510720E289F4EF2 /* InfoBubbleProbeUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoBubbleProbeUITests.swift; sourceTree = ""; }; B3413C5C263D93E79F5C6F79 /* CircleMapComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircleMapComponent.swift; sourceTree = ""; }; B454F900084472843036F8CF /* HeatmapPageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeatmapPageViewModel.swift; sourceTree = ""; }; + B536F77432B5C2C631B09DD1 /* SelectedProviderCarryOverUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectedProviderCarryOverUITests.swift; sourceTree = ""; }; B5FE164C5622D5ABA920992F /* ExampleGeoJSONStyler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleGeoJSONStyler.swift; sourceTree = ""; }; BAB49FEC2EA6F72C7A90061E /* StoreMapPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreMapPage.swift; sourceTree = ""; }; BB437D06DC85F2E05CC7F4B3 /* Sidebar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Sidebar.swift; sourceTree = ""; }; @@ -224,6 +274,7 @@ C5F51605FCA8E08A095FC699 /* ios-for-mapbox */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "ios-for-mapbox"; path = "../../ios-for-mapbox"; sourceTree = SOURCE_ROOT; }; C777804F8BD63B74CE6ED7A1 /* PolylineGeodesicPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PolylineGeodesicPage.swift; sourceTree = ""; }; C892B05755C2A7666D2F8C00 /* MapConductorSampleApp.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = MapConductorSampleApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; + C904FA9CEC6089ECA225050F /* InfoBubbleCompareUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoBubbleCompareUITests.swift; sourceTree = ""; }; CA2AB39A80E3A5C65B944467 /* PostOfficeClusterPageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostOfficeClusterPageViewModel.swift; sourceTree = ""; }; CA87900CF58E0DB99C6A3D44 /* MapConductorSampleAppUITests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = MapConductorSampleAppUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; CB0403006AA6C5EB150EABD2 /* CameraSyncTestPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraSyncTestPage.swift; sourceTree = ""; }; @@ -236,6 +287,7 @@ D764AEA50006E42D46EF8E42 /* UISettingsUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UISettingsUITests.swift; sourceTree = ""; }; D788830F4469D4610C71A869 /* RasterHeaderUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RasterHeaderUITests.swift; sourceTree = ""; }; D7C711748AE5022E33B5DCC9 /* ProviderSwitchUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProviderSwitchUITests.swift; sourceTree = ""; }; + D85F0AA9AC34D158C685AB38 /* OpenMobileMapsSmokeUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenMobileMapsSmokeUITests.swift; sourceTree = ""; }; DDCDDCC99B087D3B1329444A /* ExampleGeoJSONLayerLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExampleGeoJSONLayerLoader.swift; sourceTree = ""; }; DDCE316F0873F733D073DCFB /* TokyoPostOffices.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokyoPostOffices.swift; sourceTree = ""; }; DFA7A17FE65561B4737D7AC2 /* PostOfficePage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostOfficePage.swift; sourceTree = ""; }; @@ -244,19 +296,21 @@ E2F129A8A5CDCF49717F09F1 /* PostOfficeDataLoader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostOfficeDataLoader.swift; sourceTree = ""; }; E37BD0E38E109FB9A88C7FEF /* LongdoInfoBubbleUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LongdoInfoBubbleUITests.swift; sourceTree = ""; }; E47647DA995A6B25B95F3C3A /* PolylineClickMapPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PolylineClickMapPage.swift; sourceTree = ""; }; + E49B77569013FC71CE767C76 /* OpenMobileMapsTilingUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenMobileMapsTilingUITests.swift; sourceTree = ""; }; E4C15792FC2A80B01CD49E08 /* PolylinePageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PolylinePageViewModel.swift; sourceTree = ""; }; E60581AEC1C00F85895B924E /* PolylineMapComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PolylineMapComponent.swift; sourceTree = ""; }; E7C4718260907A3770D50458 /* FitBoundsMapComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FitBoundsMapComponent.swift; sourceTree = ""; }; E905A2A41F668FBF19BC9519 /* PolygonMapPageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PolygonMapPageViewModel.swift; sourceTree = ""; }; EB13F476A2A9A93D09A42D9E /* TiltMapPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TiltMapPage.swift; sourceTree = ""; }; ED5E4FF8CA6CC53779C785BE /* PolygonClickMapPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PolygonClickMapPage.swift; sourceTree = ""; }; + F22665DDCF354F5B3FB68973 /* ios-for-mappls */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "ios-for-mappls"; path = "../../ios-for-mappls"; sourceTree = SOURCE_ROOT; }; F23BE35F0F841264AED454DE /* SidebarItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarItem.swift; sourceTree = ""; }; F6E16C76A9F0BB857BA08951 /* GroundImagePageViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroundImagePageViewModel.swift; sourceTree = ""; }; F7A9E514E0D709DBB2647B86 /* RasterHeaderPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RasterHeaderPage.swift; sourceTree = ""; }; F9636CBE9C7019A27A04C147 /* PostOfficeClusterMapPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostOfficeClusterMapPage.swift; sourceTree = ""; }; F98B052B5A45377554CC9C2D /* StyleReloadUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StyleReloadUITests.swift; sourceTree = ""; }; + FB97E9FB4272D0D0BFCFC5AD /* ClusterZoomUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClusterZoomUITests.swift; sourceTree = ""; }; FD6BD26E6526A17508DFDE48 /* GeoJSONLayerMapPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeoJSONLayerMapPage.swift; sourceTree = ""; }; - FE117E1B8A843A840C03E8C0 /* ios-marker-clustering */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "ios-marker-clustering"; path = "../../ios-marker-clustering"; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -273,12 +327,15 @@ 15BFFF5AEE90E30A1648BF9B /* MapConductorForTomTom in Frameworks */, 754B2C5F6F912D23720FD7A9 /* MapConductorForMapTiler in Frameworks */, 21DEE995EF7CDCC705716720 /* MapConductorForLongdo in Frameworks */, - 8F6DF2FC54B36BC96B6C8BE4 /* MapConductorHeatmap in Frameworks */, - 105AB28EF7DC4395C8F056A3 /* MapConductorGeoJSON in Frameworks */, - 88D5641422025010188F524B /* MapConductorForHERE in Frameworks */, - AB3A278E630050C0B69D29C9 /* MapConductorMarkerClustering in Frameworks */, - 6F54D000AA0F05FEF5CE7E1A /* GoogleMaps in Frameworks */, - FE7DB5E571C7BD47A5729A21 /* ZIPFoundation in Frameworks */, + 8F6DF2FC54B36BC96B6C8BE4 /* MapConductorForOpenMobileMaps in Frameworks */, + 105AB28EF7DC4395C8F056A3 /* MapConductorForMappls in Frameworks */, + 88D5641422025010188F524B /* MapConductorHeatmap in Frameworks */, + AB3A278E630050C0B69D29C9 /* MapConductorGeoJSON in Frameworks */, + 6F54D000AA0F05FEF5CE7E1A /* MapConductorKML in Frameworks */, + FE7DB5E571C7BD47A5729A21 /* MapConductorForHERE in Frameworks */, + D65B9FDDBF8983CFCF3ED2F3 /* MapConductorMarkerClustering in Frameworks */, + 34FB7D29521BEE34749D62EF /* GoogleMaps in Frameworks */, + 1AAF7237622937ACB3D6450A /* ZIPFoundation in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -580,11 +637,14 @@ C5F51605FCA8E08A095FC699 /* ios-for-mapbox */, 51C699EF9F4BAE6967A14536 /* ios-for-mapkit */, 0B2B7B69B3FA403C6F675D8F /* ios-for-maplibre */, + F22665DDCF354F5B3FB68973 /* ios-for-mappls */, D729856F6C332EFE88125934 /* ios-for-maptiler */, + 59A41E8801182242AA851AD7 /* ios-for-openmobilemaps */, 2B9266EDD049DA45972FDCE9 /* ios-for-tomtom */, 2D8B401108F00801E7244C06 /* ios-geojson-layer */, 115EEADF4253AE3F62E349B7 /* ios-heatmap */, - FE117E1B8A843A840C03E8C0 /* ios-marker-clustering */, + 4B5FA1B6F9FF315058B30672 /* ios-kml */, + 7105347887569C04EFF104DE /* ios-marker-clustering */, AD9E7DD79ABF1B72A4B13050 /* ios-sdk-core */, ); name = Packages; @@ -611,6 +671,7 @@ 9DECACA325A80E44CB913DE4 /* heatmap */, 39F582A0817A67535939DBAF /* hittest */, B7B61FE3AF487F2B905B8C1A /* infobubble */, + E4D53605FED1779B723AC06D /* kml */, D58105C4BF3B711107B7106B /* map */, C157E16E11B5346736CC8A4B /* marker */, 3D1DA908927B688810F6A817 /* polygon */, @@ -625,6 +686,7 @@ isa = PBXGroup; children = ( 8281BE72BC47056A7E6108BB /* SampleMapView.swift */, + 79A12BB5733A9219AF9BC32E /* SelectedProviderStore.swift */, 05B116B454B7D9F625AF0B62 /* basic */, 74F41D93F66B1BF1D8A5C3F0 /* camerarestriction */, F4919286D669DCCC4C2D7DCF /* design */, @@ -687,23 +749,53 @@ E004F0A022CC2E77F66B45A1 /* UITests */ = { isa = PBXGroup; children = ( + 73E26429303A139633A520F2 /* A2DBubbleProbeUITests.swift */, C4C6709BFAFDBBE0C3D2504B /* CameraRestrictionUITests.swift */, + A243AD91D8C5452AD848138B /* CameraSyncArcGISUITests.swift */, + 26C59C5A1489A42CCB3E50B2 /* ClickCascadeUITests.swift */, + FB97E9FB4272D0D0BFCFC5AD /* ClusterZoomUITests.swift */, + 3B733B38F2CA606DE5F3C8A2 /* GeoJSONLayerClickUITests.swift */, + 34F95A4E1917D6BC3F5C0B82 /* GeoJSONShotUITests.swift */, AA8730F46EA8AA766554BD56 /* HeatmapCameraUITests.swift */, CFD29F27997EB2915FB99617 /* HereHitTestUITests.swift */, 08101FE49CA383BD346A656C /* HolePolygonUITests.swift */, + C904FA9CEC6089ECA225050F /* InfoBubbleCompareUITests.swift */, 4DE6402C500A3CC965F4FEF9 /* InfoBubbleCustomUITests.swift */, + B318C64E7510720E289F4EF2 /* InfoBubbleProbeUITests.swift */, + 624CDE3FBAAB41C41BFC73D4 /* InfoBubbleProjectionUITests.swift */, 539010E48B6C8FEF66E0F280 /* LargeMarkerSwitchUITests.swift */, + 8D1037C9DFD86ADDCF3863DC /* LongdoClickDiagnosticUITests.swift */, E37BD0E38E109FB9A88C7FEF /* LongdoInfoBubbleUITests.swift */, + 8C93487E79A349AC12446EDA /* MapLibreTiltZoomUITests.swift */, + 04D303901FC0014E31C66ECD /* MapplsPerfUITests.swift */, 06F98351A07D308D4D7F2A6E /* MarkerDragUITests.swift */, + 370DD0AE8450C20221B1E3E6 /* NegativeTiltUITests.swift */, + 78FB7B1699E13C53108BF653 /* OpenMobileMapsDeviceSweepUITests.swift */, + 4FE393B5A6AB91D05DD2DF77 /* OpenMobileMapsProjectionUITests.swift */, + D85F0AA9AC34D158C685AB38 /* OpenMobileMapsSmokeUITests.swift */, + E49B77569013FC71CE767C76 /* OpenMobileMapsTilingUITests.swift */, + 3D8F401557D0F3F5D9806A6E /* OverlayClickUITests.swift */, D7C711748AE5022E33B5DCC9 /* ProviderSwitchUITests.swift */, D788830F4469D4610C71A869 /* RasterHeaderUITests.swift */, + B536F77432B5C2C631B09DD1 /* SelectedProviderCarryOverUITests.swift */, 47EF2B7EE37AC5A382BFA399 /* SpiderfyUITests.swift */, + 77220E1AEF5EA1875A979D02 /* StyledBubbleUITests.swift */, F98B052B5A45377554CC9C2D /* StyleReloadUITests.swift */, D764AEA50006E42D46EF8E42 /* UISettingsUITests.swift */, + 6CEAB1031FDC359DC73B4A8A /* VisibleRegionPanelUITests.swift */, + AC34113CB0D007B466026CEF /* VisibleRegionUITests.swift */, ); path = UITests; sourceTree = ""; }; + E4D53605FED1779B723AC06D /* kml */ = { + isa = PBXGroup; + children = ( + EAEC10B68DE00E0C06B655E2 /* layer */, + ); + path = kml; + sourceTree = ""; + }; EAC80F2FE30BA27175616408 /* sidebar */ = { isa = PBXGroup; children = ( @@ -713,6 +805,14 @@ path = sidebar; sourceTree = ""; }; + EAEC10B68DE00E0C06B655E2 /* layer */ = { + isa = PBXGroup; + children = ( + 400B3C529916452091CFBFCE /* KMLLayerMapPage.swift */, + ); + path = layer; + sourceTree = ""; + }; ED4CE6C39BE8B20AD43B8184 /* raster */ = { isa = PBXGroup; children = ( @@ -796,10 +896,13 @@ 7D730C3AFB56BCACB70D7B43 /* MapConductorForTomTom */, DD849FDD6B93F3EDA511B6F1 /* MapConductorForMapTiler */, 035F4F1283704F98E8E7C663 /* MapConductorForLongdo */, + 296C0CEC881327C4C3BE65BE /* MapConductorForOpenMobileMaps */, + 54A8FE0DCEC6B7B6686369C5 /* MapConductorForMappls */, DF824C7DFDFC731E797795D6 /* MapConductorHeatmap */, A2893889C0B45F35A8DB0C4B /* MapConductorGeoJSON */, + D1071D3ED1AFC20892E4FF58 /* MapConductorKML */, C8D5A9C0CCED6456B3D81D24 /* MapConductorForHERE */, - FEB8A11AFC6869DC28064B3D /* MapConductorMarkerClustering */, + 22BC8FB0708860F782AD73DF /* MapConductorMarkerClustering */, F67792B83660D03AE335EDCD /* GoogleMaps */, CC49320174E28DBBB2DA3E3B /* ZIPFoundation */, ); @@ -864,11 +967,14 @@ EFCDB199203BBDE61A1424B1 /* XCLocalSwiftPackageReference "../../ios-for-mapbox" */, A0533065222B487AB4111AB9 /* XCLocalSwiftPackageReference "../../ios-for-mapkit" */, 3BAA3B19709CE01C24CAB943 /* XCLocalSwiftPackageReference "../../ios-for-maplibre" */, + C8E8CE55340690CF23327D70 /* XCLocalSwiftPackageReference "../../ios-for-mappls" */, BF0F2FCA7969598D48B37AF1 /* XCLocalSwiftPackageReference "../../ios-for-maptiler" */, + 9054F334F672A595D3EBBA35 /* XCLocalSwiftPackageReference "../../ios-for-openmobilemaps" */, BD32CF317AE66D8094450F62 /* XCLocalSwiftPackageReference "../../ios-for-tomtom" */, 5182F458F2DB02C7AD92C609 /* XCLocalSwiftPackageReference "../../ios-geojson-layer" */, 942816B2270F970F8C62B71B /* XCLocalSwiftPackageReference "../../ios-heatmap" */, - F49D7F82E184630C78F2E126 /* XCLocalSwiftPackageReference "../../ios-marker-clustering" */, + 8687AE3704EDFA8ED20AA08F /* XCLocalSwiftPackageReference "../../ios-kml" */, + 05117C6470473D852EB5AD45 /* XCLocalSwiftPackageReference "../../ios-marker-clustering" */, 9E8A0F65001B9CBC60F693CA /* XCLocalSwiftPackageReference "../../ios-sdk-core" */, ); preferredProjectObjectVersion = 77; @@ -899,7 +1005,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "set -euo pipefail\nRES_DIR=\"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}\"\nmkdir -p \"${RES_DIR}\"\nfor ext in png jpg jpeg zip; do\n for dir in \"${SRCROOT}/Resources\" \"${SRCROOT}/..\"; do\n for file in \"${dir}/\"*.${ext}; do\n if [ -e \"${file}\" ]; then\n cp -f \"${file}\" \"${RES_DIR}/\"\n fi\n done\n done\ndone\n"; + shellScript = "set -euo pipefail\nRES_DIR=\"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}\"\nmkdir -p \"${RES_DIR}\"\nfor ext in png jpg jpeg zip conf olf kml; do\n for dir in \"${SRCROOT}/Resources\" \"${SRCROOT}/..\"; do\n for file in \"${dir}/\"*.${ext}; do\n if [ -e \"${file}\" ]; then\n cp -f \"${file}\" \"${RES_DIR}/\"\n fi\n done\n done\ndone\n"; }; /* End PBXShellScriptBuildPhase section */ @@ -943,6 +1049,7 @@ 7AE25EB485CF3E07C6855302 /* HereHitTestPage.swift in Sources */, EC1A51ADD6A50B2BE33AE815 /* HolePolygonMapPage.swift in Sources */, D39229103CD9AC99AB00B6EA /* HolePolygonMapPageViewModel.swift in Sources */, + ECA4CD8AAA87EBD9F81ED60F /* KMLLayerMapPage.swift in Sources */, E7096B512D8CCD1AE8F80778 /* MapConductorSampleApp.swift in Sources */, 6D2317AFDDDAEB77C961EC26 /* MapDesignMapComponent.swift in Sources */, 239206A33F5255AFF2ED073D /* MapDesignMapPage.swift in Sources */, @@ -981,6 +1088,7 @@ 70FA687400503741ACC26B5E /* RichContentBubblePage.swift in Sources */, 284B63D3105246B496337FDC /* SampleConfig.swift in Sources */, A92A4D5BB420A460B5E6FED4 /* SampleMapView.swift in Sources */, + CA785F8851B74FD7C1541F12 /* SelectedProviderStore.swift in Sources */, 62B38FB816A90530C5E94533 /* Sidebar.swift in Sources */, A902BC97B29AFA4BBBD8310A /* SidebarItem.swift in Sources */, F0B349FC52422B6A48908AA2 /* SimpleTextBubblePage.swift in Sources */, @@ -1005,19 +1113,41 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + B0A1D3E58CCB8244F30FBBF4 /* A2DBubbleProbeUITests.swift in Sources */, 6BD87DE57C766D0BB384A240 /* CameraRestrictionUITests.swift in Sources */, + 6F6897312AA41B79421BA95C /* CameraSyncArcGISUITests.swift in Sources */, + 723CFFDF4FA4EABD8736B916 /* ClickCascadeUITests.swift in Sources */, + 79AB161A992A0CC73CB58A3B /* ClusterZoomUITests.swift in Sources */, + 3FE6EE1DAC0F59D7B38B2957 /* GeoJSONLayerClickUITests.swift in Sources */, + 2B286E8D0C115213181B1916 /* GeoJSONShotUITests.swift in Sources */, CB49E4C305852E171446DA2E /* HeatmapCameraUITests.swift in Sources */, 4B0BA6BA90381FC6641DD555 /* HereHitTestUITests.swift in Sources */, B2B112AA7F88521C3FD10FDD /* HolePolygonUITests.swift in Sources */, + 4FC1432266AE069EF90AB666 /* InfoBubbleCompareUITests.swift in Sources */, 8FB9E5BE76F30E432DCC8174 /* InfoBubbleCustomUITests.swift in Sources */, + 7F051E3CC34D18CFF6850A62 /* InfoBubbleProbeUITests.swift in Sources */, + 6099B1F9204EDECA514773D4 /* InfoBubbleProjectionUITests.swift in Sources */, E467A41D66C8BF026BD956B7 /* LargeMarkerSwitchUITests.swift in Sources */, + FACC823631EE4D95873171EE /* LongdoClickDiagnosticUITests.swift in Sources */, 0AE7FB160024B8B485EB15EB /* LongdoInfoBubbleUITests.swift in Sources */, + BEC3F92921F126CF3DA899C5 /* MapLibreTiltZoomUITests.swift in Sources */, + 1091E30A026F66E8E1F46EE4 /* MapplsPerfUITests.swift in Sources */, 9BE1985582B254F7E7F9E77F /* MarkerDragUITests.swift in Sources */, + 794BB5070971B2EB50A47273 /* NegativeTiltUITests.swift in Sources */, + 2B5770AF7FE2A6CE91E433D4 /* OpenMobileMapsDeviceSweepUITests.swift in Sources */, + 75B989F4A6C7BC3F59FE580B /* OpenMobileMapsProjectionUITests.swift in Sources */, + D136C9B97EE353605F49E3B3 /* OpenMobileMapsSmokeUITests.swift in Sources */, + E50D539EAE73B4B82765B647 /* OpenMobileMapsTilingUITests.swift in Sources */, + F563F6AF3F992969EC8A5B17 /* OverlayClickUITests.swift in Sources */, 39BD7B6F805E581E3ECD665D /* ProviderSwitchUITests.swift in Sources */, 7B21D76122110C43BD9D414F /* RasterHeaderUITests.swift in Sources */, + 77D622AF5E9B3C7036591F63 /* SelectedProviderCarryOverUITests.swift in Sources */, 58EDB1BF6B43FC714812ED94 /* SpiderfyUITests.swift in Sources */, A955322BEA38C109B9581248 /* StyleReloadUITests.swift in Sources */, + A9C5ACDF37AF9C73F8F32118 /* StyledBubbleUITests.swift in Sources */, 17B5F2B2856E7710BC987153 /* UISettingsUITests.swift in Sources */, + 55FC9049CBE1797978FE5401 /* VisibleRegionPanelUITests.swift in Sources */, + FD16826298AAADD228089FA1 /* VisibleRegionUITests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1156,7 +1286,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 17.0; + IPHONEOS_DEPLOYMENT_TARGET = 18.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -1218,7 +1348,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 17.0; + IPHONEOS_DEPLOYMENT_TARGET = 18.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; @@ -1263,6 +1393,10 @@ /* End XCConfigurationList section */ /* Begin XCLocalSwiftPackageReference section */ + 05117C6470473D852EB5AD45 /* XCLocalSwiftPackageReference "../../ios-marker-clustering" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = "../../ios-marker-clustering"; + }; 3BAA3B19709CE01C24CAB943 /* XCLocalSwiftPackageReference "../../ios-for-maplibre" */ = { isa = XCLocalSwiftPackageReference; relativePath = "../../ios-for-maplibre"; @@ -1279,6 +1413,14 @@ isa = XCLocalSwiftPackageReference; relativePath = "../../ios-for-googlemaps"; }; + 8687AE3704EDFA8ED20AA08F /* XCLocalSwiftPackageReference "../../ios-kml" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = "../../ios-kml"; + }; + 9054F334F672A595D3EBBA35 /* XCLocalSwiftPackageReference "../../ios-for-openmobilemaps" */ = { + isa = XCLocalSwiftPackageReference; + relativePath = "../../ios-for-openmobilemaps"; + }; 942816B2270F970F8C62B71B /* XCLocalSwiftPackageReference "../../ios-heatmap" */ = { isa = XCLocalSwiftPackageReference; relativePath = "../../ios-heatmap"; @@ -1303,13 +1445,13 @@ isa = XCLocalSwiftPackageReference; relativePath = "../../ios-for-maptiler"; }; - EFCDB199203BBDE61A1424B1 /* XCLocalSwiftPackageReference "../../ios-for-mapbox" */ = { + C8E8CE55340690CF23327D70 /* XCLocalSwiftPackageReference "../../ios-for-mappls" */ = { isa = XCLocalSwiftPackageReference; - relativePath = "../../ios-for-mapbox"; + relativePath = "../../ios-for-mappls"; }; - F49D7F82E184630C78F2E126 /* XCLocalSwiftPackageReference "../../ios-marker-clustering" */ = { + EFCDB199203BBDE61A1424B1 /* XCLocalSwiftPackageReference "../../ios-for-mapbox" */ = { isa = XCLocalSwiftPackageReference; - relativePath = "../../ios-marker-clustering"; + relativePath = "../../ios-for-mapbox"; }; FEDBBDD983CCFED337925652 /* XCLocalSwiftPackageReference "../../ios-for-here" */ = { isa = XCLocalSwiftPackageReference; @@ -1323,7 +1465,7 @@ repositoryURL = "https://github.com/googlemaps/ios-maps-sdk"; requirement = { kind = exactVersion; - version = 10.7.0; + version = 11.0.0; }; }; EA9904C5DC8D915C46A8309E /* XCRemoteSwiftPackageReference "ZIPFoundation" */ = { @@ -1349,6 +1491,18 @@ isa = XCSwiftPackageProductDependency; productName = MapConductorForMapbox; }; + 22BC8FB0708860F782AD73DF /* MapConductorMarkerClustering */ = { + isa = XCSwiftPackageProductDependency; + productName = MapConductorMarkerClustering; + }; + 296C0CEC881327C4C3BE65BE /* MapConductorForOpenMobileMaps */ = { + isa = XCSwiftPackageProductDependency; + productName = MapConductorForOpenMobileMaps; + }; + 54A8FE0DCEC6B7B6686369C5 /* MapConductorForMappls */ = { + isa = XCSwiftPackageProductDependency; + productName = MapConductorForMappls; + }; 5F868FD6810605D51D8DE0E0 /* MapConductorCore */ = { isa = XCSwiftPackageProductDependency; productName = MapConductorCore; @@ -1378,6 +1532,10 @@ package = EA9904C5DC8D915C46A8309E /* XCRemoteSwiftPackageReference "ZIPFoundation" */; productName = ZIPFoundation; }; + D1071D3ED1AFC20892E4FF58 /* MapConductorKML */ = { + isa = XCSwiftPackageProductDependency; + productName = MapConductorKML; + }; DD849FDD6B93F3EDA511B6F1 /* MapConductorForMapTiler */ = { isa = XCSwiftPackageProductDependency; productName = MapConductorForMapTiler; @@ -1395,10 +1553,6 @@ package = 27DBF6E8902DBA1D9B9323F0 /* XCRemoteSwiftPackageReference "ios-maps-sdk" */; productName = GoogleMaps; }; - FEB8A11AFC6869DC28064B3D /* MapConductorMarkerClustering */ = { - isa = XCSwiftPackageProductDependency; - productName = MapConductorMarkerClustering; - }; /* End XCSwiftPackageProductDependency section */ }; rootObject = 027B56AE645A6E8D32E682FE /* Project object */; diff --git a/samples/MapConductorSampleApp/MapConductorSampleApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/samples/MapConductorSampleApp/MapConductorSampleApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 6f76357..909e94b 100644 --- a/samples/MapConductorSampleApp/MapConductorSampleApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/samples/MapConductorSampleApp/MapConductorSampleApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -5,8 +5,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/Esri/arcgis-maps-sdk-swift", "state" : { - "revision" : "6926d003e5ab19b0114f9690e6f7f31fdb2a2814", - "version" : "200.8.2" + "revision" : "fbd6c04e9c5b94af6556488de1e770bacf44fc3a", + "version" : "300.1.0" } }, { @@ -14,8 +14,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/googlemaps/ios-maps-sdk", "state" : { - "revision" : "dcfc4b6dda80bf7a748c34996af823be96511cc1", - "version" : "10.7.0" + "revision" : "c37c4946d60f0ab069476d5781053b837771546e", + "version" : "11.0.0" } }, { @@ -63,6 +63,42 @@ "version" : "6.27.0" } }, + { + "identity" : "mappls-api-core-ios-distribution", + "kind" : "remoteSourceControl", + "location" : "https://github.com/mappls-api/mappls-api-core-ios-distribution.git", + "state" : { + "revision" : "8f69fc59f1ca2c46ed7a7925bc9d5030cdb258ef", + "version" : "2.1.3" + } + }, + { + "identity" : "mappls-api-kit-ios-distribution", + "kind" : "remoteSourceControl", + "location" : "https://github.com/mappls-api/mappls-api-kit-ios-distribution.git", + "state" : { + "revision" : "d1476e11bcfea4c34e53bbcfd6792cbcb13f8c2c", + "version" : "3.0.6" + } + }, + { + "identity" : "mappls-map-ios-distribution", + "kind" : "remoteSourceControl", + "location" : "https://github.com/mappls-api/mappls-map-ios-distribution.git", + "state" : { + "revision" : "51a5b77c788595b272afb9a4e83a4283c36f4f04", + "version" : "6.1.5" + } + }, + { + "identity" : "swift-atomics", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-atomics.git", + "state" : { + "revision" : "0442cb5a3f98ab802acb777929fdb446bda11a34", + "version" : "1.3.1" + } + }, { "identity" : "swifter", "kind" : "remoteSourceControl", diff --git a/samples/MapConductorSampleApp/MapConductorSampleApp.xcodeproj/project.xcworkspace/xcuserdata/masashi.xcuserdatad/UserInterfaceState.xcuserstate b/samples/MapConductorSampleApp/MapConductorSampleApp.xcodeproj/project.xcworkspace/xcuserdata/masashi.xcuserdatad/UserInterfaceState.xcuserstate index f3974a3..03a3ff9 100644 Binary files a/samples/MapConductorSampleApp/MapConductorSampleApp.xcodeproj/project.xcworkspace/xcuserdata/masashi.xcuserdatad/UserInterfaceState.xcuserstate and b/samples/MapConductorSampleApp/MapConductorSampleApp.xcodeproj/project.xcworkspace/xcuserdata/masashi.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/samples/MapConductorSampleApp/MapConductorSampleApp.xcworkspace/xcshareddata/swiftpm/Package.resolved b/samples/MapConductorSampleApp/MapConductorSampleApp.xcworkspace/xcshareddata/swiftpm/Package.resolved index defcb1c..292d6ec 100644 --- a/samples/MapConductorSampleApp/MapConductorSampleApp.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/samples/MapConductorSampleApp/MapConductorSampleApp.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -5,8 +5,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/Esri/arcgis-maps-sdk-swift", "state" : { - "revision" : "6926d003e5ab19b0114f9690e6f7f31fdb2a2814", - "version" : "200.8.2" + "revision" : "fbd6c04e9c5b94af6556488de1e770bacf44fc3a", + "version" : "300.1.0" } }, { @@ -14,8 +14,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/googlemaps/ios-maps-sdk", "state" : { - "revision" : "dcfc4b6dda80bf7a748c34996af823be96511cc1", - "version" : "10.7.0" + "revision" : "c37c4946d60f0ab069476d5781053b837771546e", + "version" : "11.0.0" } }, { @@ -63,6 +63,42 @@ "version" : "6.24.0" } }, + { + "identity" : "mappls-api-core-ios-distribution", + "kind" : "remoteSourceControl", + "location" : "https://github.com/mappls-api/mappls-api-core-ios-distribution.git", + "state" : { + "revision" : "8f69fc59f1ca2c46ed7a7925bc9d5030cdb258ef", + "version" : "2.1.3" + } + }, + { + "identity" : "mappls-api-kit-ios-distribution", + "kind" : "remoteSourceControl", + "location" : "https://github.com/mappls-api/mappls-api-kit-ios-distribution.git", + "state" : { + "revision" : "d1476e11bcfea4c34e53bbcfd6792cbcb13f8c2c", + "version" : "3.0.6" + } + }, + { + "identity" : "mappls-map-ios-distribution", + "kind" : "remoteSourceControl", + "location" : "https://github.com/mappls-api/mappls-map-ios-distribution.git", + "state" : { + "revision" : "51a5b77c788595b272afb9a4e83a4283c36f4f04", + "version" : "6.1.5" + } + }, + { + "identity" : "swift-atomics", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-atomics.git", + "state" : { + "revision" : "0442cb5a3f98ab802acb777929fdb446bda11a34", + "version" : "1.3.1" + } + }, { "identity" : "swifter", "kind" : "remoteSourceControl", diff --git a/samples/MapConductorSampleApp/Resources/N02-22_GML.zip b/samples/MapConductorSampleApp/Resources/N02-22_GML.zip index f673fad..baed25a 100644 Binary files a/samples/MapConductorSampleApp/Resources/N02-22_GML.zip and b/samples/MapConductorSampleApp/Resources/N02-22_GML.zip differ diff --git a/samples/MapConductorSampleApp/Resources/city_honolulu.png b/samples/MapConductorSampleApp/Resources/city_honolulu.png new file mode 100644 index 0000000..c528c83 Binary files /dev/null and b/samples/MapConductorSampleApp/Resources/city_honolulu.png differ diff --git a/samples/MapConductorSampleApp/Resources/city_london.png b/samples/MapConductorSampleApp/Resources/city_london.png new file mode 100644 index 0000000..8c819b9 Binary files /dev/null and b/samples/MapConductorSampleApp/Resources/city_london.png differ diff --git a/samples/MapConductorSampleApp/Resources/city_newyork.png b/samples/MapConductorSampleApp/Resources/city_newyork.png new file mode 100644 index 0000000..60128c3 Binary files /dev/null and b/samples/MapConductorSampleApp/Resources/city_newyork.png differ diff --git a/samples/MapConductorSampleApp/Resources/city_sydney.png b/samples/MapConductorSampleApp/Resources/city_sydney.png new file mode 100644 index 0000000..ccb1240 Binary files /dev/null and b/samples/MapConductorSampleApp/Resources/city_sydney.png differ diff --git a/samples/MapConductorSampleApp/Resources/city_tokyo.png b/samples/MapConductorSampleApp/Resources/city_tokyo.png new file mode 100644 index 0000000..15d4557 Binary files /dev/null and b/samples/MapConductorSampleApp/Resources/city_tokyo.png differ diff --git a/samples/MapConductorSampleApp/Resources/sample.kml b/samples/MapConductorSampleApp/Resources/sample.kml new file mode 100644 index 0000000..164c805 --- /dev/null +++ b/samples/MapConductorSampleApp/Resources/sample.kml @@ -0,0 +1,116 @@ + + + + MapConductor KML Sample + + + + + + + + + + normal + #bluePoly + + + highlight + #bluePoly + + + + + Imperial Palace Area + A polygon with a hole near the Imperial Palace. + #bluePolyMap + + + + + 139.744,35.688,0 + 139.762,35.688,0 + 139.762,35.676,0 + 139.744,35.676,0 + 139.744,35.688,0 + + + + + + + 139.750,35.685,0 + 139.756,35.685,0 + 139.756,35.680,0 + 139.750,35.680,0 + 139.750,35.685,0 + + + + + + + + Chuo Line (approx.) + A red poly-line running east to west. + #redLine + + + 139.700,35.700,0 + 139.730,35.695,0 + 139.770,35.690,0 + 139.810,35.700,0 + + + + + + Tokyo Station + A styled point placemark. + #greenPoint + + + station + + + + 139.767,35.681,0 + + + + + Points of Interest + + Ginza + + 139.764,35.671,0 + + + + Akihabara + + 139.774,35.698,0 + + + + + diff --git a/samples/MapConductorSampleApp/Sources/DemoAppScreen.swift b/samples/MapConductorSampleApp/Sources/DemoAppScreen.swift index b659eae..ad8fa00 100644 --- a/samples/MapConductorSampleApp/Sources/DemoAppScreen.swift +++ b/samples/MapConductorSampleApp/Sources/DemoAppScreen.swift @@ -102,6 +102,11 @@ struct DemoAppScreen: View { SidebarItem(id: "geojson-basic", title: "GeoJSON"), SidebarItem(id: "geojson-layer", title: "GeoJSON Layer") ] + ), + SidebarSection( + id: "kml", + title: "KML", + items: [SidebarItem(id: "kml-layer", title: "KML Layer")] ) ] @@ -161,6 +166,8 @@ struct DemoAppScreen: View { BasicGeoJSONMapPage(onToggleSidebar: navigationViewModel.toggleSidebar) case "geojson-layer": GeoJSONLayerMapPage(onToggleSidebar: navigationViewModel.toggleSidebar) + case "kml-layer": + KMLLayerMapPage(onToggleSidebar: navigationViewModel.toggleSidebar) case "polygon-basic": PolygonMapPage(onToggleSidebar: navigationViewModel.toggleSidebar) case "polygon-click": diff --git a/samples/MapConductorSampleApp/Sources/MapConductorSampleApp.swift b/samples/MapConductorSampleApp/Sources/MapConductorSampleApp.swift index 6d932fe..e061c84 100644 --- a/samples/MapConductorSampleApp/Sources/MapConductorSampleApp.swift +++ b/samples/MapConductorSampleApp/Sources/MapConductorSampleApp.swift @@ -2,6 +2,16 @@ import SwiftUI @main struct MapConductorSampleApp: App { + init() { + // `MAPCONDUCTOR_SAMPLE_PROVIDER` / `--provider` は**開始時のプロバイダ**の指定。 + // 覚えている選択として一度だけ置き、あとはユーザーが選んだときと同じ扱いにする。 + // 各ページから毎回読むと、指定が常時の上書きになってページを移るたびに + // 元のプロバイダへ戻ってしまう。 + if let provider = MapProvider.fromLaunch() { + MainActor.assumeIsolated { SelectedProviderStore.remember(provider) } + } + } + var body: some Scene { WindowGroup { ContentView() diff --git a/samples/MapConductorSampleApp/Sources/pages/camerasync/CameraSyncTestPage.swift b/samples/MapConductorSampleApp/Sources/pages/camerasync/CameraSyncTestPage.swift index 1176485..81b639c 100644 --- a/samples/MapConductorSampleApp/Sources/pages/camerasync/CameraSyncTestPage.swift +++ b/samples/MapConductorSampleApp/Sources/pages/camerasync/CameraSyncTestPage.swift @@ -8,6 +8,8 @@ import MapConductorForHERE import MapConductorForTomTom import MapConductorForMapTiler import MapConductorForLongdo +import MapConductorForOpenMobileMaps +import MapConductorForMappls import SwiftUI import GoogleMaps @@ -24,6 +26,8 @@ struct CameraSyncTestPage: View { @StateObject private var leftTomTomState: TomTomMapViewState @StateObject private var leftMapTilerState: MapTilerViewState @StateObject private var leftLongdoState: LongdoViewState + @StateObject private var leftOpenMobileMapsState: OpenMobileMapsViewState + @StateObject private var leftMapplsState: MapplsViewState @StateObject private var rightGoogleState: GoogleMapViewState @StateObject private var rightMapLibreState: MapLibreViewState @@ -34,6 +38,8 @@ struct CameraSyncTestPage: View { @StateObject private var rightTomTomState: TomTomMapViewState @StateObject private var rightMapTilerState: MapTilerViewState @StateObject private var rightLongdoState: LongdoViewState + @StateObject private var rightOpenMobileMapsState: OpenMobileMapsViewState + @StateObject private var rightMapplsState: MapplsViewState // Camera state displayed in the info panels @State private var leftCameraPosition: MapCameraPosition @@ -79,6 +85,8 @@ struct CameraSyncTestPage: View { _leftTomTomState = StateObject(wrappedValue: TomTomMapViewState(mapDesignType: TomTomMapDesign.Standard, cameraPosition: vm.initCameraPosition)) _leftMapTilerState = StateObject(wrappedValue: MapTilerViewState(mapDesignType: MapTilerDesign.Streets, cameraPosition: vm.initCameraPosition)) _leftLongdoState = StateObject(wrappedValue: LongdoViewState(mapDesignType: LongdoDesign.Normal, cameraPosition: vm.initCameraPosition)) + _leftOpenMobileMapsState = StateObject(wrappedValue: OpenMobileMapsViewState(mapDesignType: OpenMobileMapsDesign.openStreetMap, cameraPosition: vm.initCameraPosition)) + _leftMapplsState = StateObject(wrappedValue: MapplsViewState(mapDesignType: MapplsDesign.Default, cameraPosition: vm.initCameraPosition)) _rightGoogleState = StateObject(wrappedValue: GoogleMapViewState(cameraPosition: vm.initCameraPosition)) _rightMapLibreState = StateObject(wrappedValue: MapLibreViewState(mapDesignType: MapLibreDesign.OsmBright, cameraPosition: vm.initCameraPosition)) @@ -89,6 +97,8 @@ struct CameraSyncTestPage: View { _rightTomTomState = StateObject(wrappedValue: TomTomMapViewState(mapDesignType: TomTomMapDesign.Standard, cameraPosition: vm.initCameraPosition)) _rightMapTilerState = StateObject(wrappedValue: MapTilerViewState(mapDesignType: MapTilerDesign.Streets, cameraPosition: vm.initCameraPosition)) _rightLongdoState = StateObject(wrappedValue: LongdoViewState(mapDesignType: LongdoDesign.Normal, cameraPosition: vm.initCameraPosition)) + _rightOpenMobileMapsState = StateObject(wrappedValue: OpenMobileMapsViewState(mapDesignType: OpenMobileMapsDesign.openStreetMap, cameraPosition: vm.initCameraPosition)) + _rightMapplsState = StateObject(wrappedValue: MapplsViewState(mapDesignType: MapplsDesign.Default, cameraPosition: vm.initCameraPosition)) } var body: some View { @@ -337,6 +347,18 @@ struct CameraSyncTestPage: View { } else { Text("Longdo is not available due to no API key") } + case .openMobileMaps: + OpenMobileMapsMapView( + state: side == .left ? leftOpenMobileMapsState : rightOpenMobileMapsState, + onCameraMove: onMove, + onCameraMoveEnd: onMoveEnd + ) { mapContent() } + case .mappls: + MapplsMapView( + state: side == .left ? leftMapplsState : rightMapplsState, + onCameraMove: onMove, + onCameraMoveEnd: onMoveEnd + ) { mapContent() } } } @@ -509,6 +531,8 @@ struct CameraSyncTestPage: View { case .tomTom: leftTomTomState.moveCameraTo(cameraPosition: position, durationMillis: duration) case .mapTiler: leftMapTilerState.moveCameraTo(cameraPosition: position, durationMillis: duration) case .longdo: leftLongdoState.moveCameraTo(cameraPosition: position, durationMillis: duration) + case .openMobileMaps: leftOpenMobileMapsState.moveCameraTo(cameraPosition: position, durationMillis: duration) + case .mappls: leftMapplsState.moveCameraTo(cameraPosition: position, durationMillis: duration) } } @@ -523,6 +547,8 @@ struct CameraSyncTestPage: View { case .tomTom: rightTomTomState.moveCameraTo(cameraPosition: position, durationMillis: duration) case .mapTiler: rightMapTilerState.moveCameraTo(cameraPosition: position, durationMillis: duration) case .longdo: rightLongdoState.moveCameraTo(cameraPosition: position, durationMillis: duration) + case .openMobileMaps: rightOpenMobileMapsState.moveCameraTo(cameraPosition: position, durationMillis: duration) + case .mappls: rightMapplsState.moveCameraTo(cameraPosition: position, durationMillis: duration) } } diff --git a/samples/MapConductorSampleApp/Sources/pages/camerasync/CameraSyncTestViewModel.swift b/samples/MapConductorSampleApp/Sources/pages/camerasync/CameraSyncTestViewModel.swift index 18b0a3a..f99dd60 100644 --- a/samples/MapConductorSampleApp/Sources/pages/camerasync/CameraSyncTestViewModel.swift +++ b/samples/MapConductorSampleApp/Sources/pages/camerasync/CameraSyncTestViewModel.swift @@ -14,11 +14,13 @@ class CameraSyncTestViewModel: ObservableObject { /// 左右のプロバイダは環境変数でも指定できる(UI テスト用)。 /// 左は他ページと同じ `MAPCONDUCTOR_SAMPLE_PROVIDER`、右は `..._RIGHT`。 @Published var leftProvider: MapProvider = .initial(fallback: .googleMaps) - @Published var rightProvider: MapProvider = .initial( - environmentKey: "MAPCONDUCTOR_SAMPLE_PROVIDER_RIGHT", - argumentName: "--providerRight", - fallback: .mapLibre - ) + /// 右ペインは直近の選択を引き継がない。引き継ぐと左右が同じプロバイダになり、 + /// 見比べるためのページとして成り立たなくなる。 + @Published var rightProvider: MapProvider = + MapProvider.fromLaunch( + environmentKey: "MAPCONDUCTOR_SAMPLE_PROVIDER_RIGHT", + argumentName: "--providerRight" + ) ?? .mapLibre let initCameraPosition = MapCameraPosition( position: GeoPoint(latitude: 35.6812, longitude: 139.7671, altitude: 0), // Tokyo @@ -129,6 +131,10 @@ class CameraSyncTestViewModel: ObservableObject { return "MapTiler" case .longdo: return "Longdo" + case .openMobileMaps: + return "Open Mobile Maps" + case .mappls: + return "Mappls" } } } diff --git a/samples/MapConductorSampleApp/Sources/pages/circle/CircleMapComponent.swift b/samples/MapConductorSampleApp/Sources/pages/circle/CircleMapComponent.swift index 2748b3a..be230f7 100644 --- a/samples/MapConductorSampleApp/Sources/pages/circle/CircleMapComponent.swift +++ b/samples/MapConductorSampleApp/Sources/pages/circle/CircleMapComponent.swift @@ -9,6 +9,8 @@ import MapConductorForHERE import MapConductorForTomTom import MapConductorForMapTiler import MapConductorForLongdo +import MapConductorForOpenMobileMaps +import MapConductorForMappls import SwiftUI import UIKit @@ -23,6 +25,8 @@ struct CircleMapComponent: View { @ObservedObject var tomTomState: TomTomMapViewState @ObservedObject var mapTilerState: MapTilerViewState @ObservedObject var longdoState: LongdoViewState + @ObservedObject var openMobileMapsState: OpenMobileMapsViewState + @ObservedObject var mapplsState: MapplsViewState @ObservedObject var viewModel: CirclePageViewModel @State private var labelPosition: CGPoint? @@ -40,6 +44,8 @@ struct CircleMapComponent: View { tomTomState: tomTomState, mapTilerState: mapTilerState, longdoState: longdoState, + openMobileMapsState: openMobileMapsState, + mapplsState: mapplsState, onCameraMove: { _ in calculateLabelPosition() } ) { { () -> MapViewContent in @@ -92,6 +98,9 @@ struct CircleMapComponent: View { case .tomTom: return tomTomState.getMapViewHolder() case .mapTiler: return mapTilerState.getMapViewHolder() case .longdo: return longdoState.getMapViewHolder() + case .openMobileMaps: return openMobileMapsState.getMapViewHolder() + + case .mappls: return mapplsState.getMapViewHolder() } } } diff --git a/samples/MapConductorSampleApp/Sources/pages/circle/CircleMapPage.swift b/samples/MapConductorSampleApp/Sources/pages/circle/CircleMapPage.swift index 7c0a476..3457f3b 100644 --- a/samples/MapConductorSampleApp/Sources/pages/circle/CircleMapPage.swift +++ b/samples/MapConductorSampleApp/Sources/pages/circle/CircleMapPage.swift @@ -8,6 +8,8 @@ import MapConductorForHERE import MapConductorForTomTom import MapConductorForMapTiler import MapConductorForLongdo +import MapConductorForOpenMobileMaps +import MapConductorForMappls import SwiftUI struct CircleMapPage: View { @@ -25,6 +27,8 @@ struct CircleMapPage: View { @StateObject private var tomTomState: TomTomMapViewState @StateObject private var mapTilerState: MapTilerViewState @StateObject private var longdoState: LongdoViewState + @StateObject private var openMobileMapsState: OpenMobileMapsViewState + @StateObject private var mapplsState: MapplsViewState init(onToggleSidebar: @escaping () -> Void = {}) { self.onToggleSidebar = onToggleSidebar @@ -79,6 +83,18 @@ struct CircleMapPage: View { cameraPosition: vm.initCameraPosition ) ) + _openMobileMapsState = StateObject( + wrappedValue: OpenMobileMapsViewState( + mapDesignType: OpenMobileMapsDesign.openStreetMap, + cameraPosition: vm.initCameraPosition + ) + ) + _mapplsState = StateObject( + wrappedValue: MapplsViewState( + mapDesignType: MapplsDesign.Default, + cameraPosition: vm.initCameraPosition + ) + ) } var body: some View { @@ -95,6 +111,8 @@ struct CircleMapPage: View { tomTomState: tomTomState, mapTilerState: mapTilerState, longdoState: longdoState, + openMobileMapsState: openMobileMapsState, + mapplsState: mapplsState, viewModel: viewModel ) diff --git a/samples/MapConductorSampleApp/Sources/pages/geojson/basic/BasicGeoJSONMapPage.swift b/samples/MapConductorSampleApp/Sources/pages/geojson/basic/BasicGeoJSONMapPage.swift index 8340d73..dfe8dd6 100644 --- a/samples/MapConductorSampleApp/Sources/pages/geojson/basic/BasicGeoJSONMapPage.swift +++ b/samples/MapConductorSampleApp/Sources/pages/geojson/basic/BasicGeoJSONMapPage.swift @@ -1,5 +1,7 @@ import MapConductorCore import MapConductorForLongdo +import MapConductorForOpenMobileMaps +import MapConductorForMappls import MapConductorForArcGIS import MapConductorForGoogleMaps import MapConductorForHERE @@ -27,6 +29,8 @@ struct BasicGeoJSONMapPage: View { @StateObject private var tomTomState: TomTomMapViewState @StateObject private var mapTilerState: MapTilerViewState @StateObject private var longdoState: LongdoViewState + @StateObject private var openMobileMapsState: OpenMobileMapsViewState + @StateObject private var mapplsState: MapplsViewState init(onToggleSidebar: @escaping () -> Void = {}) { self.onToggleSidebar = onToggleSidebar @@ -87,6 +91,18 @@ struct BasicGeoJSONMapPage: View { cameraPosition: cameraPosition ) ) + _openMobileMapsState = StateObject( + wrappedValue: OpenMobileMapsViewState( + mapDesignType: OpenMobileMapsDesign.openStreetMap, + cameraPosition: cameraPosition + ) + ) + _mapplsState = StateObject( + wrappedValue: MapplsViewState( + mapDesignType: MapplsDesign.Default, + cameraPosition: cameraPosition + ) + ) } var body: some View { @@ -103,6 +119,8 @@ struct BasicGeoJSONMapPage: View { tomTomState: tomTomState, mapTilerState: mapTilerState, longdoState: longdoState, + openMobileMapsState: openMobileMapsState, + mapplsState: mapplsState, ) { GeoJSONLayer(state: layerState, features: basicGeoJSONFeatures) } diff --git a/samples/MapConductorSampleApp/Sources/pages/geojson/layer/GeoJSONLayerMapPage.swift b/samples/MapConductorSampleApp/Sources/pages/geojson/layer/GeoJSONLayerMapPage.swift index 73e68cd..7088c40 100644 --- a/samples/MapConductorSampleApp/Sources/pages/geojson/layer/GeoJSONLayerMapPage.swift +++ b/samples/MapConductorSampleApp/Sources/pages/geojson/layer/GeoJSONLayerMapPage.swift @@ -8,6 +8,8 @@ import MapConductorForMapKit import MapConductorForMapLibre import MapConductorForMapbox import MapConductorForLongdo +import MapConductorForOpenMobileMaps +import MapConductorForMappls import MapConductorGeoJSON import SwiftUI import UIKit @@ -27,6 +29,8 @@ struct GeoJSONLayerMapPage: View { @StateObject private var tomTomState: TomTomMapViewState @StateObject private var mapTilerState: MapTilerViewState @StateObject private var longdoState: LongdoViewState + @StateObject private var openMobileMapsState: OpenMobileMapsViewState + @StateObject private var mapplsState: MapplsViewState @State private var features: [GeoJSONFeature] = [] @State private var selectedFeature: GeoJSONFeature? @@ -46,7 +50,10 @@ struct GeoJSONLayerMapPage: View { pointRadius: 8 ) - _provider = State(initialValue: .mapLibre) + // 他のページと同じく、選択中のプロバイダを引き継ぐ。ここだけ `.mapLibre` を + // 決め打ちしていたので、サイドバーから来ると必ず MapLibre に戻っていた。 + // android の GeoJSONLayerMapPage は共通の選択をそのまま使う。 + _provider = State(initialValue: MapProvider.initial()) _layerState = StateObject(wrappedValue: GeoJSONLayerState(layerStyle: style)) _googleState = StateObject(wrappedValue: GoogleMapViewState(cameraPosition: cameraPosition)) _mapLibreState = StateObject( @@ -92,6 +99,18 @@ struct GeoJSONLayerMapPage: View { cameraPosition: cameraPosition ) ) + _openMobileMapsState = StateObject( + wrappedValue: OpenMobileMapsViewState( + mapDesignType: OpenMobileMapsDesign.openStreetMap, + cameraPosition: cameraPosition + ) + ) + _mapplsState = StateObject( + wrappedValue: MapplsViewState( + mapDesignType: MapplsDesign.Default, + cameraPosition: cameraPosition + ) + ) } var body: some View { @@ -108,6 +127,8 @@ struct GeoJSONLayerMapPage: View { tomTomState: tomTomState, mapTilerState: mapTilerState, longdoState: longdoState, + openMobileMapsState: openMobileMapsState, + mapplsState: mapplsState, onMapClick: handleMapClick ) { GeoJSONLayer(state: layerState, features: features) @@ -160,7 +181,32 @@ struct GeoJSONLayerMapPage: View { private func handleMapClick(_ geoPoint: GeoPoint) { selectedFeature = nil tappedPosition = nil - layerState.processClick(geoPoint: geoPoint, pixelTolerance: 10, zoom: googleState.cameraPosition.zoom) + // ★ **選択中のプロバイダ**のズームを渡すこと。 + // + // ここは `googleState.cameraPosition.zoom` を固定で渡していた。Google 以外を + // 選んでいるあいだ Google の state は更新されないので、初期ズームのまま止まり、 + // 画素の許容量を世界座標へ直す係数が実際の縮尺と食い違う。ズームすればするほど + // ずれて、**線をタップしても何も選ばれない**という形で出る。 + // android / react は最初から選択中の state のズームを渡している。 + layerState.processClick(geoPoint: geoPoint, pixelTolerance: 10, zoom: activeCameraZoom) + } + + /// 選択中のプロバイダのカメラのズーム。 + private var activeCameraZoom: Double { + switch provider { + case .googleMaps: return googleState.cameraPosition.zoom + case .mapLibre: return mapLibreState.cameraPosition.zoom + case .mapKit: return mapKitState.cameraPosition.zoom + case .mapbox: return mapboxState.cameraPosition.zoom + case .arcGIS, .arcGIS2D: return arcGISState.cameraPosition.zoom + case .here: return hereState.cameraPosition.zoom + case .tomTom: return tomTomState.cameraPosition.zoom + case .mapTiler: return mapTilerState.cameraPosition.zoom + case .longdo: return longdoState.cameraPosition.zoom + case .openMobileMaps: return openMobileMapsState.cameraPosition.zoom + + case .mappls: return mapplsState.cameraPosition.zoom + } } private func loadFeaturesIfNeeded() { @@ -182,19 +228,57 @@ struct GeoJSONLayerMapPage: View { private struct PropertyTable: View { let properties: [String: Any] + /// 国土数値情報の鉄道データ(N02)の属性名。 + /// + /// 生の `N02_001` のままだと何の値か分からないので、吹き出しでは名前に置き換える。 + /// react / android と**同じ文言**にしてある(3 プラットフォームを並べて見比べるサンプルなので、 + /// ここが違うと同じ地物を選んでいるのか判断できない)。 + /// + /// ここに無いキーは生のキー名をそのまま出す。データ側に属性が増えても表から消えないように。 + private static let labels = [ + "N02_001": (ja: "鉄道区分", en: "Railway category"), + "N02_002": (ja: "事業者区分", en: "Business category"), + "N02_003": (ja: "路線名", en: "Railway name"), + "N02_004": (ja: "運営会社", en: "Railway company"), + ] + + /// 値の英語表記が入っている属性の接尾辞。 + /// + /// geojson 側が `N02_003`(路線名)に対して `N02_003_en` を持っている。アプリに + /// 対訳表を置くと 4 プラットフォーム分そろえる羽目になるので、データに持たせてある。 + private static let englishSuffix = "_en" + + private var isJapanese: Bool { Locale.current.language.languageCode?.identifier == "ja" } + + /// 端末の言語が日本語なら日本語、それ以外は英語で出す。 + /// `_en` の行そのものは出さない(同じ項目が 2 行に増えてしまうため)。 var body: some View { ScrollView { VStack(spacing: 0) { - PropertyRow(name: "Property", value: "Value", isHeader: true) + PropertyRow( + name: isJapanese ? "プロパティ" : "Property", + value: isJapanese ? "値" : "Value", + isHeader: true + ) - ForEach(properties.keys.sorted(), id: \.self) { key in - PropertyRow(name: key, value: formatPropertyValue(properties[key]), isHeader: false) + ForEach(properties.keys.sorted().filter { !$0.hasSuffix(Self.englishSuffix) }, id: \.self) { key in + PropertyRow( + name: Self.labels[key].map { isJapanese ? $0.ja : $0.en } ?? key, + value: formatPropertyValue(value(for: key)), + isHeader: false + ) } } } + // 320pt より広げない。iPhone の横幅では吹き出しが画面外へはみ出す。 .frame(width: 320) .frame(maxHeight: 300) } + + private func value(for key: String) -> Any? { + if isJapanese { return properties[key] } + return properties[key + Self.englishSuffix] ?? properties[key] + } } private struct PropertyRow: View { @@ -204,8 +288,8 @@ private struct PropertyRow: View { var body: some View { HStack(spacing: 0) { - cell(name, width: 120) - cell(value, width: 200) + cell(name, width: 160) + cell(value, width: 160) } .background(isHeader ? Color(UIColor.systemGray5) : Color.clear) } diff --git a/samples/MapConductorSampleApp/Sources/pages/groundimage/GroundImageMapComponent.swift b/samples/MapConductorSampleApp/Sources/pages/groundimage/GroundImageMapComponent.swift index 8a7dfcf..581e85b 100644 --- a/samples/MapConductorSampleApp/Sources/pages/groundimage/GroundImageMapComponent.swift +++ b/samples/MapConductorSampleApp/Sources/pages/groundimage/GroundImageMapComponent.swift @@ -9,6 +9,8 @@ import MapConductorForHERE import MapConductorForTomTom import MapConductorForMapTiler import MapConductorForLongdo +import MapConductorForOpenMobileMaps +import MapConductorForMappls import SwiftUI struct GroundImageMapComponent: View { @@ -22,6 +24,8 @@ struct GroundImageMapComponent: View { @ObservedObject var tomTomState: TomTomMapViewState @ObservedObject var mapTilerState: MapTilerViewState @ObservedObject var longdoState: LongdoViewState + @ObservedObject var openMobileMapsState: OpenMobileMapsViewState + @ObservedObject var mapplsState: MapplsViewState @ObservedObject var viewModel: GroundImagePageViewModel var body: some View { @@ -35,10 +39,14 @@ struct GroundImageMapComponent: View { hereState: hereState, tomTomState: tomTomState, mapTilerState: mapTilerState, - longdoState: longdoState + longdoState: longdoState, + openMobileMapsState: openMobileMapsState, + mapplsState: mapplsState ) { { () -> MapViewContent in var content = MapViewContent() + // 画像の外周をなぞる矩形。 + content.polylines = [Polyline(state: viewModel.framePolyline)] content.markers = viewModel.markers.map { Marker(state: $0) } content.groundImages = [GroundImage(state: viewModel.groundImageState)] return content diff --git a/samples/MapConductorSampleApp/Sources/pages/groundimage/GroundImageMapPage.swift b/samples/MapConductorSampleApp/Sources/pages/groundimage/GroundImageMapPage.swift index 8bfe6cd..dedb7c7 100644 --- a/samples/MapConductorSampleApp/Sources/pages/groundimage/GroundImageMapPage.swift +++ b/samples/MapConductorSampleApp/Sources/pages/groundimage/GroundImageMapPage.swift @@ -8,6 +8,8 @@ import MapConductorForHERE import MapConductorForTomTom import MapConductorForMapTiler import MapConductorForLongdo +import MapConductorForOpenMobileMaps +import MapConductorForMappls import SwiftUI import UIKit @@ -26,6 +28,8 @@ struct GroundImageMapPage: View { @StateObject private var tomTomState: TomTomMapViewState @StateObject private var mapTilerState: MapTilerViewState @StateObject private var longdoState: LongdoViewState + @StateObject private var openMobileMapsState: OpenMobileMapsViewState + @StateObject private var mapplsState: MapplsViewState init(onToggleSidebar: @escaping () -> Void = {}) { self.onToggleSidebar = onToggleSidebar @@ -70,6 +74,14 @@ struct GroundImageMapPage: View { mapDesignType: LongdoDesign.Normal, cameraPosition: vm.initCameraPosition )) + _openMobileMapsState = StateObject(wrappedValue: OpenMobileMapsViewState( + mapDesignType: OpenMobileMapsDesign.openStreetMap, + cameraPosition: vm.initCameraPosition + )) + _mapplsState = StateObject(wrappedValue: MapplsViewState( + mapDesignType: MapplsDesign.Default, + cameraPosition: vm.initCameraPosition + )) } var body: some View { @@ -86,6 +98,8 @@ struct GroundImageMapPage: View { tomTomState: tomTomState, mapTilerState: mapTilerState, longdoState: longdoState, + openMobileMapsState: openMobileMapsState, + mapplsState: mapplsState, viewModel: viewModel ) @@ -172,6 +186,10 @@ struct GroundImageMapPage: View { return mapTilerState case .longdo: return longdoState + case .openMobileMaps: + return openMobileMapsState + case .mappls: + return mapplsState } } diff --git a/samples/MapConductorSampleApp/Sources/pages/groundimage/GroundImagePageViewModel.swift b/samples/MapConductorSampleApp/Sources/pages/groundimage/GroundImagePageViewModel.swift index 16bb9e5..f3421ed 100644 --- a/samples/MapConductorSampleApp/Sources/pages/groundimage/GroundImagePageViewModel.swift +++ b/samples/MapConductorSampleApp/Sources/pages/groundimage/GroundImagePageViewModel.swift @@ -9,6 +9,13 @@ final class GroundImagePageViewModel: ObservableObject { let groundImageState: GroundImageState let markers: [MarkerState] + /// グラウンドイメージの外周をなぞる矩形。 + /// + /// NE → NW → SW → SE → NE の順に 5 点で閉じる。SW / NE の 2 点だけでは + /// **画像がどこまで載っているのかが見えない**ので、ドラッグで範囲を変えたときの + /// 手応えを出すために引いている。android / react のサンプルと同じ構成。 + let framePolyline: PolylineState + @Published var opacity: Double @Published var tilt: Double @Published var message: String? = nil @@ -81,6 +88,13 @@ final class GroundImagePageViewModel: ObservableObject { self.markers = [southWestMarker, northEastMarker] + self.framePolyline = PolylineState( + points: GroundImagePageViewModel.framePoints(southWest: southWest, northEast: northEast), + id: "groundimage-frame", + strokeColor: .white, + strokeWidth: 3.0 + ) + self.groundImageState.onClick = { [weak self] event in self?.onGroundImageClick(event) } @@ -156,6 +170,23 @@ final class GroundImagePageViewModel: ObservableObject { bounds.extend(point: sw) bounds.extend(point: ne) } + + // `points` を差し替えるだけで再描画される。インスタンスは作り直さない + // (作り直すとドラッグ中に id が変わってちらつく)。 + framePolyline.points = GroundImagePageViewModel.framePoints(southWest: sw, northEast: ne) + } + + /// 2 つの角から矩形の 4 辺をなぞる点列を作る。NE → NW → SW → SE → NE で閉じる。 + /// + /// ドラッグで南北・東西が反転しても、常に 2 点を対角とする矩形になる。 + private static func framePoints(southWest: GeoPoint, northEast: GeoPoint) -> [GeoPoint] { + [ + northEast, + GeoPoint(latitude: northEast.latitude, longitude: southWest.longitude, altitude: 0), + southWest, + GeoPoint(latitude: southWest.latitude, longitude: northEast.longitude, altitude: 0), + northEast, + ] } private static func calculateMarkerLabels(southWest: GeoPoint, northEast: GeoPoint) -> (String, String) { diff --git a/samples/MapConductorSampleApp/Sources/pages/heatmap/HeatmapMapComponent.swift b/samples/MapConductorSampleApp/Sources/pages/heatmap/HeatmapMapComponent.swift index 1f3f012..02eb6cc 100644 --- a/samples/MapConductorSampleApp/Sources/pages/heatmap/HeatmapMapComponent.swift +++ b/samples/MapConductorSampleApp/Sources/pages/heatmap/HeatmapMapComponent.swift @@ -1,5 +1,7 @@ import GoogleMaps import MapConductorForLongdo +import MapConductorForOpenMobileMaps +import MapConductorForMappls import MapConductorCore import MapConductorForGoogleMaps import MapConductorForMapLibre @@ -24,6 +26,8 @@ struct HeatmapMapComponent: View { @ObservedObject var tomTomState: TomTomMapViewState @ObservedObject var mapTilerState: MapTilerViewState @ObservedObject var longdoState: LongdoViewState + @ObservedObject var openMobileMapsState: OpenMobileMapsViewState + @ObservedObject var mapplsState: MapplsViewState let heatmap: HeatmapOverlayState let points: [HeatmapPointState] @@ -41,6 +45,8 @@ struct HeatmapMapComponent: View { tomTomState: tomTomState, mapTilerState: mapTilerState, longdoState: longdoState, + openMobileMapsState: openMobileMapsState, + mapplsState: mapplsState, onCameraMove: nil, onCameraMoveEnd: { camera in onCameraMove(provider, camera) diff --git a/samples/MapConductorSampleApp/Sources/pages/heatmap/HeatmapMapPage.swift b/samples/MapConductorSampleApp/Sources/pages/heatmap/HeatmapMapPage.swift index b24ae2f..3b8970b 100644 --- a/samples/MapConductorSampleApp/Sources/pages/heatmap/HeatmapMapPage.swift +++ b/samples/MapConductorSampleApp/Sources/pages/heatmap/HeatmapMapPage.swift @@ -8,6 +8,8 @@ import MapConductorForHERE import MapConductorForTomTom import MapConductorForMapTiler import MapConductorForLongdo +import MapConductorForOpenMobileMaps +import MapConductorForMappls import MapConductorHeatmap import SwiftUI @@ -26,6 +28,8 @@ struct HeatmapMapPage: View { @StateObject private var tomTomState: TomTomMapViewState @StateObject private var mapTilerState: MapTilerViewState @StateObject private var longdoState: LongdoViewState + @StateObject private var openMobileMapsState: OpenMobileMapsViewState + @StateObject private var mapplsState: MapplsViewState init(onToggleSidebar: @escaping () -> Void = {}) { self.onToggleSidebar = onToggleSidebar @@ -79,6 +83,18 @@ struct HeatmapMapPage: View { cameraPosition: vm.initCameraPosition ) ) + _openMobileMapsState = StateObject( + wrappedValue: OpenMobileMapsViewState( + mapDesignType: OpenMobileMapsDesign.openStreetMap, + cameraPosition: vm.initCameraPosition + ) + ) + _mapplsState = StateObject( + wrappedValue: MapplsViewState( + mapDesignType: MapplsDesign.Default, + cameraPosition: vm.initCameraPosition + ) + ) } var body: some View { @@ -95,6 +111,8 @@ struct HeatmapMapPage: View { tomTomState: tomTomState, mapTilerState: mapTilerState, longdoState: longdoState, + openMobileMapsState: openMobileMapsState, + mapplsState: mapplsState, heatmap: viewModel.heatmap, points: viewModel.heatmapPoints, onCameraMove: viewModel.onCameraMove(provider:camera:) diff --git a/samples/MapConductorSampleApp/Sources/pages/infobubble/MultipleBubblesPage.swift b/samples/MapConductorSampleApp/Sources/pages/infobubble/MultipleBubblesPage.swift index d659bb9..56183d7 100644 --- a/samples/MapConductorSampleApp/Sources/pages/infobubble/MultipleBubblesPage.swift +++ b/samples/MapConductorSampleApp/Sources/pages/infobubble/MultipleBubblesPage.swift @@ -9,6 +9,8 @@ import MapConductorForMapKit import MapConductorForMapbox import MapConductorForArcGIS import MapConductorForLongdo +import MapConductorForOpenMobileMaps +import MapConductorForMappls import SwiftUI import UIKit @@ -88,6 +90,20 @@ struct MultipleBubblesPage: View { zoom: 15 ) ) + @StateObject private var openMobileMapsState = OpenMobileMapsViewState( + mapDesignType: OpenMobileMapsDesign.openStreetMap, + cameraPosition: MapCameraPosition( + position: GeoPoint(latitude: 37.7749, longitude: -122.4194), + zoom: 15 + ) + ) + @StateObject private var mapplsState = MapplsViewState( + mapDesignType: MapplsDesign.Default, + cameraPosition: MapCameraPosition( + position: GeoPoint(latitude: 37.7749, longitude: -122.4194), + zoom: 15 + ) + ) private let markerState1 = MarkerState( position: GeoPoint(latitude: 37.7749, longitude: -122.4194), @@ -123,6 +139,8 @@ struct MultipleBubblesPage: View { tomTomState: tomTomState, mapTilerState: mapTilerState, longdoState: longdoState, + openMobileMapsState: openMobileMapsState, + mapplsState: mapplsState, onMapClick: { _ in selectedMarkers = [] } diff --git a/samples/MapConductorSampleApp/Sources/pages/infobubble/RichContentBubblePage.swift b/samples/MapConductorSampleApp/Sources/pages/infobubble/RichContentBubblePage.swift index 930d0a1..dd59443 100644 --- a/samples/MapConductorSampleApp/Sources/pages/infobubble/RichContentBubblePage.swift +++ b/samples/MapConductorSampleApp/Sources/pages/infobubble/RichContentBubblePage.swift @@ -1,5 +1,7 @@ import GoogleMaps import MapConductorForLongdo +import MapConductorForOpenMobileMaps +import MapConductorForMappls import MapConductorCore import MapConductorForGoogleMaps import MapConductorForMapLibre @@ -95,6 +97,20 @@ struct RichContentBubblePage: View { zoom: 10 ) ) + @StateObject private var openMobileMapsState = OpenMobileMapsViewState( + mapDesignType: OpenMobileMapsDesign.openStreetMap, + cameraPosition: MapCameraPosition( + position: GeoPoint(latitude: 37.7749, longitude: -122.4194), + zoom: 10 + ) + ) + @StateObject private var mapplsState = MapplsViewState( + mapDesignType: MapplsDesign.Default, + cameraPosition: MapCameraPosition( + position: GeoPoint(latitude: 37.7749, longitude: -122.4194), + zoom: 10 + ) + ) @StateObject private var markerState = MarkerState( position: GeoPoint(latitude: 37.7694, longitude: -122.4862), @@ -119,6 +135,8 @@ struct RichContentBubblePage: View { tomTomState: tomTomState, mapTilerState: mapTilerState, longdoState: longdoState, + openMobileMapsState: openMobileMapsState, + mapplsState: mapplsState, onMapClick: { _ in selectedMarker = nil } ) { Marker(state: markerState) diff --git a/samples/MapConductorSampleApp/Sources/pages/infobubble/SimpleTextBubblePage.swift b/samples/MapConductorSampleApp/Sources/pages/infobubble/SimpleTextBubblePage.swift index b215222..cb9baf3 100644 --- a/samples/MapConductorSampleApp/Sources/pages/infobubble/SimpleTextBubblePage.swift +++ b/samples/MapConductorSampleApp/Sources/pages/infobubble/SimpleTextBubblePage.swift @@ -1,5 +1,7 @@ import GoogleMaps import MapConductorForLongdo +import MapConductorForOpenMobileMaps +import MapConductorForMappls import MapConductorCore import MapConductorForGoogleMaps import MapConductorForMapLibre @@ -88,6 +90,20 @@ struct SimpleTextBubblePage: View { zoom: 10 ) ) + @StateObject private var openMobileMapsState = OpenMobileMapsViewState( + mapDesignType: OpenMobileMapsDesign.openStreetMap, + cameraPosition: MapCameraPosition( + position: GeoPoint(latitude: 37.7749, longitude: -122.4194), + zoom: 10 + ) + ) + @StateObject private var mapplsState = MapplsViewState( + mapDesignType: MapplsDesign.Default, + cameraPosition: MapCameraPosition( + position: GeoPoint(latitude: 37.7749, longitude: -122.4194), + zoom: 10 + ) + ) @StateObject private var markerState = MarkerState( position: GeoPoint(latitude: 37.7749, longitude: -122.4194), @@ -108,6 +124,8 @@ struct SimpleTextBubblePage: View { tomTomState: tomTomState, mapTilerState: mapTilerState, longdoState: longdoState, + openMobileMapsState: openMobileMapsState, + mapplsState: mapplsState, onMapClick: { _ in selectedMarker = nil } ) { Marker(state: markerState) @@ -118,6 +136,11 @@ struct SimpleTextBubblePage: View { Text(marker.extra as! String) .foregroundColor(.accentColor) .padding(4) + // UI テスト用。吹き出しは UIHostingController 経由で + // PassthroughContainerView に載るため、プロバイダによっては + // staticTexts からもラベル検索からも見つからない(maplibre / mapkit で確認)。 + // 識別子を付けておくとどのプロバイダでも決定的に取れる。 + .accessibilityIdentifier("infoBubbleText") } } diff --git a/samples/MapConductorSampleApp/Sources/pages/infobubble/StyledInfoBubblePage.swift b/samples/MapConductorSampleApp/Sources/pages/infobubble/StyledInfoBubblePage.swift index 675185d..f401d0e 100644 --- a/samples/MapConductorSampleApp/Sources/pages/infobubble/StyledInfoBubblePage.swift +++ b/samples/MapConductorSampleApp/Sources/pages/infobubble/StyledInfoBubblePage.swift @@ -9,8 +9,14 @@ import MapConductorForHERE import MapConductorForTomTom import MapConductorForMapTiler import MapConductorForLongdo +import MapConductorForOpenMobileMaps +import MapConductorForMappls import SwiftUI +/// android の StyledInfoBubblePage.kt / react の StyledInfoBubblePage.tsx と同一仕様: +/// マーカー 1 個と常時表示の InfoBubble を置き、パネルの 8 色スウォッチ 4 行 +/// (バブル塗り / バブル枠線 / 文字 / マーカー)と 2 本のスライダー +/// (枠線幅・マーカースケール 0.5〜2.0、0.25 刻み)でスタイルを組み替える。 struct StyledInfoBubblePage: View { let onToggleSidebar: () -> Void @@ -18,201 +24,166 @@ struct StyledInfoBubblePage: View { self.onToggleSidebar = onToggleSidebar } + private static let startPosition = GeoPoint(latitude: 35.6812, longitude: 139.7671) + + /// 4 行で共有する 8 色。白と黒を含めておくと塗り=白 / 文字=黒の既定も同じ列で選べる。 + private static let palette: [Color] = [ + Color(red: 1.00, green: 1.00, blue: 1.00), + Color(red: 0.07, green: 0.09, blue: 0.15), + Color(red: 0.94, green: 0.27, blue: 0.27), + Color(red: 0.98, green: 0.45, blue: 0.09), + Color(red: 0.92, green: 0.70, blue: 0.03), + Color(red: 0.13, green: 0.77, blue: 0.37), + Color(red: 0.23, green: 0.51, blue: 0.96), + Color(red: 0.66, green: 0.33, blue: 0.97), + ] + @State private var provider: MapProvider = MapProvider.initial() + @State private var fillColor: Color = StyledInfoBubblePage.palette[0] + @State private var strokeColor: Color = StyledInfoBubblePage.palette[1] + @State private var fontColor: Color = StyledInfoBubblePage.palette[1] + @State private var markerColor: Color = StyledInfoBubblePage.palette[2] + @State private var strokeWidth: Double = 2.0 + @State private var markerScale: Double = 1.0 + @StateObject private var googleState = GoogleMapViewState( - cameraPosition: MapCameraPosition( - position: GeoPoint(latitude: 35.6812, longitude: 139.7671), - zoom: 12 - ) + cameraPosition: MapCameraPosition(position: startPosition, zoom: 14) ) - @StateObject private var mapLibreState = MapLibreViewState( mapDesignType: MapLibreDesign.DemoTiles, - cameraPosition: MapCameraPosition( - position: GeoPoint(latitude: 35.6812, longitude: 139.7671), - zoom: 12 - ) + cameraPosition: MapCameraPosition(position: startPosition, zoom: 14) ) - @StateObject private var mapKitState = MapKitViewState( mapDesignType: MapKitMapDesign.Standard, - cameraPosition: MapCameraPosition( - position: GeoPoint(latitude: 35.6812, longitude: 139.7671), - zoom: 12 - ) + cameraPosition: MapCameraPosition(position: startPosition, zoom: 14) ) - @StateObject private var mapboxState = MapboxViewState( - cameraPosition: MapCameraPosition( - position: GeoPoint(latitude: 35.6812, longitude: 139.7671), - zoom: 12 - ) + cameraPosition: MapCameraPosition(position: startPosition, zoom: 14) ) - @StateObject private var arcGISState = ArcGISMapViewState( mapDesignType: ArcGISDesign.OsmStandard, - cameraPosition: MapCameraPosition( - position: GeoPoint(latitude: 35.6812, longitude: 139.7671), - zoom: 12 - ) + cameraPosition: MapCameraPosition(position: startPosition, zoom: 14) ) - @StateObject private var hereState = HereMapViewState( mapDesignType: HereMapDesign.NormalDay, - cameraPosition: MapCameraPosition( - position: GeoPoint(latitude: 35.6812, longitude: 139.7671), - zoom: 12 - ) + cameraPosition: MapCameraPosition(position: startPosition, zoom: 14) ) @StateObject private var tomTomState = TomTomMapViewState( mapDesignType: TomTomMapDesign.Standard, - cameraPosition: MapCameraPosition( - position: GeoPoint(latitude: 35.6812, longitude: 139.7671), - zoom: 12 - ) + cameraPosition: MapCameraPosition(position: startPosition, zoom: 14) ) @StateObject private var mapTilerState = MapTilerViewState( mapDesignType: MapTilerDesign.Streets, - cameraPosition: MapCameraPosition( - position: GeoPoint(latitude: 35.6812, longitude: 139.7671), - zoom: 12 - ) + cameraPosition: MapCameraPosition(position: startPosition, zoom: 14) ) - @StateObject private var longdoState = LongdoViewState( mapDesignType: LongdoDesign.Normal, - cameraPosition: MapCameraPosition( - position: GeoPoint(latitude: 35.6812, longitude: 139.7671), - zoom: 12 - ) + cameraPosition: MapCameraPosition(position: startPosition, zoom: 14) ) - - @StateObject private var markerState = MarkerState( - position: GeoPoint(latitude: 35.6812, longitude: 139.7671) + @StateObject private var openMobileMapsState = OpenMobileMapsViewState( + mapDesignType: OpenMobileMapsDesign.openStreetMap, + cameraPosition: MapCameraPosition(position: startPosition, zoom: 14) ) - - /// Second marker, used to demo `InfoBubbleCustom` — content drawn entirely by us, - /// tail included. Mirrors the Android example's `InfoBubbleCustom` section. - @StateObject private var customMarkerState = MarkerState( - position: GeoPoint(latitude: 35.6812, longitude: 139.7971) + @StateObject private var mapplsState = MapplsViewState( + mapDesignType: MapplsDesign.Default, + cameraPosition: MapCameraPosition(position: startPosition, zoom: 14) ) + @StateObject private var markerState = MarkerState( + position: startPosition, + id: "styled-bubble-marker", + icon: DefaultMarkerIcon(fillColor: UIColor(red: 0.94, green: 0.27, blue: 0.27, alpha: 1)) + ) var body: some View { DemoMapPageScaffold(provider: $provider, onToggleSidebar: onToggleSidebar) { - SampleMapView( - provider: $provider, - googleState: googleState, - mapLibreState: mapLibreState, - mapKitState: mapKitState, - mapboxState: mapboxState, - arcGISState: arcGISState, - hereState: hereState, - tomTomState: tomTomState, - mapTilerState: mapTilerState, - longdoState: longdoState, - onMapClick: { point in markerState.position = point } - ) { - Marker(state: markerState) - InfoBubble( - marker: markerState, - bubbleColor: Color.black.opacity(0.85), - borderColor: Color.white, - contentPadding: 10, - cornerRadius: 10, - tailSize: 10 + ZStack { + SampleMapView( + provider: $provider, + googleState: googleState, + mapLibreState: mapLibreState, + mapKitState: mapKitState, + mapboxState: mapboxState, + arcGISState: arcGISState, + hereState: hereState, + tomTomState: tomTomState, + mapTilerState: mapTilerState, + longdoState: longdoState, + openMobileMapsState: openMobileMapsState, + mapplsState: mapplsState ) { - VStack(alignment: .leading, spacing: 6) { - Text("Night Mode") - .font(.headline) - .foregroundColor(.white) - Text("Custom style bubble") - .font(.subheadline) - .foregroundColor(.white.opacity(0.8)) + Marker(state: markerState) + InfoBubble( + marker: markerState, + bubbleColor: fillColor, + borderColor: strokeColor, + borderWidth: strokeWidth, + contentPadding: 10, + cornerRadius: 6 + ) { + Text("Custom Styled Bubble") + .font(.subheadline.weight(.semibold)) + .foregroundColor(fontColor) + .fixedSize() } } - Marker(state: customMarkerState) - // The tail is part of our own drawing, so tell the overlay engine that - // the connection point sits at the content box's center-left. - InfoBubbleCustom( - marker: customMarkerState, - tailOffset: CGPoint(x: 0, y: 0.5) - ) { - RightTailInfoBubble(bubbleColor: .white, borderColor: .black) { - Text("Fully custom bubble") - .font(.subheadline) - .foregroundColor(.accentColor) - } - } + controlPanel + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .bottomLeading) } } + .onChange(of: markerColor) { _ in updateMarkerIcon() } + .onChange(of: markerScale) { _ in updateMarkerIcon() } } -} -/// A bubble that sits to the right of its marker, with the tail on its own left edge. -/// Ported from the Android example's `RightTailInfoBubble` composable. -private struct RightTailInfoBubble: View { - var bubbleColor: Color = .white - var borderColor: Color = .black - var contentPadding: CGFloat = 8 - var cornerRadius: CGFloat = 4 - var tailSize: CGFloat = 8 - @ViewBuilder var content: Content - - private var shape: RightTailBubbleShape { - RightTailBubbleShape(tail: tailSize, corner: cornerRadius) + private func updateMarkerIcon() { + markerState.icon = DefaultMarkerIcon( + fillColor: UIColor(markerColor), + scale: CGFloat(markerScale) + ) } - var body: some View { - content - .padding(contentPadding) - .padding(.leading, tailSize) - .background(shape.fill(bubbleColor)) - .overlay(shape.stroke(borderColor, lineWidth: 1)) + private var controlPanel: some View { + VStack(alignment: .leading, spacing: 8) { + swatchRow(label: "Fill", selected: $fillColor) + swatchRow(label: "Stroke", selected: $strokeColor) + swatchRow(label: "Font", selected: $fontColor) + swatchRow(label: "Marker", selected: $markerColor) + Text(String(format: "Stroke Width: %.2f", strokeWidth)) + .font(.caption) + Slider(value: $strokeWidth, in: 0.5...2.0, step: 0.25) + Text(String(format: "Marker Scale: %.2f", markerScale)) + .font(.caption) + Slider(value: $markerScale, in: 0.5...2.0, step: 0.25) + } + .padding(16) + .background(Color(UIColor.systemBackground).opacity(0.95)) + .cornerRadius(12) + .shadow(color: Color.black.opacity(0.2), radius: 8, x: 0, y: 4) + .padding(.leading, 16) + .padding(.bottom, 16) } -} - -/// Rounded rect occupying `x ∈ [tail, width]`, plus a triangular tail pointing left -/// from the vertical center — so the tail tip lands at the box's `(0, 0.5)`. -private struct RightTailBubbleShape: Shape { - let tail: CGFloat - let corner: CGFloat - - func path(in rect: CGRect) -> Path { - let left = rect.minX + tail - let right = rect.maxX - let top = rect.minY - let bottom = rect.maxY - let midY = rect.midY - var path = Path() - path.move(to: CGPoint(x: left + corner, y: top)) - path.addArc( - tangent1End: CGPoint(x: right, y: top), - tangent2End: CGPoint(x: right, y: bottom), - radius: corner - ) - path.addArc( - tangent1End: CGPoint(x: right, y: bottom), - tangent2End: CGPoint(x: left, y: bottom), - radius: corner - ) - path.addArc( - tangent1End: CGPoint(x: left, y: bottom), - tangent2End: CGPoint(x: left, y: top), - radius: corner - ) - path.addLine(to: CGPoint(x: left, y: midY + tail / 2)) - path.addLine(to: CGPoint(x: rect.minX, y: midY)) - path.addLine(to: CGPoint(x: left, y: midY - tail / 2)) - path.addArc( - tangent1End: CGPoint(x: left, y: top), - tangent2End: CGPoint(x: right, y: top), - radius: corner - ) - path.closeSubpath() - return path + private func swatchRow(label: String, selected: Binding) -> some View { + HStack(spacing: 6) { + Text(label) + .font(.caption) + .frame(width: 52, alignment: .leading) + ForEach(Array(Self.palette.enumerated()), id: \.offset) { _, color in + Circle() + .fill(color) + .frame(width: 18, height: 18) + .overlay( + Circle().stroke( + selected.wrappedValue == color + ? Color(red: 0.15, green: 0.39, blue: 0.92) + : Color.black.opacity(0.25), + lineWidth: selected.wrappedValue == color ? 2 : 1 + ) + ) + .onTapGesture { selected.wrappedValue = color } + } + } } } diff --git a/samples/MapConductorSampleApp/Sources/pages/kml/layer/KMLLayerMapPage.swift b/samples/MapConductorSampleApp/Sources/pages/kml/layer/KMLLayerMapPage.swift new file mode 100644 index 0000000..179d446 --- /dev/null +++ b/samples/MapConductorSampleApp/Sources/pages/kml/layer/KMLLayerMapPage.swift @@ -0,0 +1,307 @@ +import MapConductorCore +import MapConductorForArcGIS +import MapConductorForGoogleMaps +import MapConductorForHERE +import MapConductorForTomTom +import MapConductorForMapTiler +import MapConductorForMapKit +import MapConductorForMapLibre +import MapConductorForMapbox +import MapConductorForLongdo +import MapConductorForOpenMobileMaps +import MapConductorForMappls +import MapConductorKML +import SwiftUI +import UIKit + +struct KMLLayerMapPage: View { + let onToggleSidebar: () -> Void + + @State private var provider: MapProvider + @StateObject private var layerState: KMLLayerState + + @StateObject private var googleState: GoogleMapViewState + @StateObject private var mapLibreState: MapLibreViewState + @StateObject private var mapKitState: MapKitViewState + @StateObject private var mapboxState: MapboxViewState + @StateObject private var arcGISState: ArcGISMapViewState + @StateObject private var hereState: HereMapViewState + @StateObject private var tomTomState: TomTomMapViewState + @StateObject private var mapTilerState: MapTilerViewState + @StateObject private var longdoState: LongdoViewState + @StateObject private var openMobileMapsState: OpenMobileMapsViewState + @StateObject private var mapplsState: MapplsViewState + + @State private var features: [KMLFeature] = [] + @State private var selectedFeature: KMLFeature? + @State private var tappedPosition: GeoPoint? + @State private var isDataLoading = true + + init(onToggleSidebar: @escaping () -> Void = {}) { + self.onToggleSidebar = onToggleSidebar + let cameraPosition = MapCameraPosition( + position: GeoPoint(latitude: 35.685, longitude: 139.76), + zoom: 13.0 + ) + // Fallback style used when a placemark carries no KML