Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
4B0000011111111111111128 /* arena_concert.png in Resources */ = {isa = PBXBuildFile; fileRef = 4B0000010000000000000018 /* arena_concert.png */; };
4B0000011111111111111129 /* Mappedin in Frameworks */ = {isa = PBXBuildFile; productRef = 4B0000020000000000000001 /* Mappedin */; };
D175A38A2EF9CE9600F925EF /* LocationsDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D175A3892EF9CE9300F925EF /* LocationsDemoViewController.swift */; };
D175A3962EFB239A00F925EF /* StackedMapsDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D175A3942EFB239A00F925EF /* StackedMapsDemoViewController.swift */; };
D175A3972EFB239A00F925EF /* StackedMapsUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = D175A3952EFB239A00F925EF /* StackedMapsUtils.swift */; };
D175A3982EFB239A00F925EF /* MultiFloorViewDemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D175A3932EFB239A00F925EF /* MultiFloorViewDemoViewController.swift */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
Expand Down Expand Up @@ -63,6 +66,9 @@
4B0000010000000000000019 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
4B000001000000000000001A /* PlaygroundSamples.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PlaygroundSamples.app; sourceTree = BUILT_PRODUCTS_DIR; };
D175A3892EF9CE9300F925EF /* LocationsDemoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationsDemoViewController.swift; sourceTree = "<group>"; };
D175A3932EFB239A00F925EF /* MultiFloorViewDemoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiFloorViewDemoViewController.swift; sourceTree = "<group>"; };
D175A3942EFB239A00F925EF /* StackedMapsDemoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StackedMapsDemoViewController.swift; sourceTree = "<group>"; };
D175A3952EFB239A00F925EF /* StackedMapsUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StackedMapsUtils.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand All @@ -88,32 +94,35 @@
4B0000040000000000000002 /* PlaygroundSamples */ = {
isa = PBXGroup;
children = (
D175A3892EF9CE9300F925EF /* LocationsDemoViewController.swift */,
4B0000010000000000000015 /* 3d_assets */,
4B0000010000000000000001 /* AppDelegate.swift */,
4B0000010000000000000002 /* SceneDelegate.swift */,
4B0000010000000000000003 /* ViewController.swift */,
4B0000010000000000000007 /* DisplayMapDemoViewController.swift */,
4B0000010000000000000008 /* AreaShapesDemoViewController.swift */,
4B0000010000000000000017 /* arena_basketball.png */,
4B0000010000000000000018 /* arena_concert.png */,
4B0000010000000000000016 /* arena_hockey.png */,
4B0000010000000000000005 /* Assets.xcassets */,
4B0000010000000000000009 /* BuildingFloorSelectionDemoViewController.swift */,
4B000001000000000000000A /* CameraDemoViewController.swift */,
4B0000010000000000000007 /* DisplayMapDemoViewController.swift */,
4B000001000000000000000B /* Image3DDemoViewController.swift */,
4B0000010000000000000019 /* Info.plist */,
4B000001000000000000000C /* InteractivityDemoViewController.swift */,
4B000001000000000000000D /* LabelsDemoViewController.swift */,
4B0000040000000000000005 /* LaunchScreen.storyboard */,
D175A3892EF9CE9300F925EF /* LocationsDemoViewController.swift */,
4B0000040000000000000004 /* Main.storyboard */,
4B000001000000000000000E /* MarkersDemoViewController.swift */,
4B0000010000000000000014 /* model_positions.json */,
4B000001000000000000000F /* ModelsDemoViewController.swift */,
D175A3932EFB239A00F925EF /* MultiFloorViewDemoViewController.swift */,
4B0000010000000000000010 /* NavigationDemoViewController.swift */,
4B0000010000000000000011 /* PathsDemoViewController.swift */,
4B0000010000000000000012 /* QueryDemoViewController.swift */,
4B0000010000000000000002 /* SceneDelegate.swift */,
4B0000010000000000000013 /* SearchDemoViewController.swift */,
4B0000040000000000000004 /* Main.storyboard */,
4B0000010000000000000005 /* Assets.xcassets */,
4B0000040000000000000005 /* LaunchScreen.storyboard */,
4B0000010000000000000019 /* Info.plist */,
4B0000010000000000000014 /* model_positions.json */,
4B0000010000000000000015 /* 3d_assets */,
4B0000010000000000000016 /* arena_hockey.png */,
4B0000010000000000000017 /* arena_basketball.png */,
4B0000010000000000000018 /* arena_concert.png */,
D175A3942EFB239A00F925EF /* StackedMapsDemoViewController.swift */,
D175A3952EFB239A00F925EF /* StackedMapsUtils.swift */,
4B0000010000000000000003 /* ViewController.swift */,
);
path = PlaygroundSamples;
sourceTree = "<group>";
Expand Down Expand Up @@ -215,6 +224,9 @@
4B0000011111111111111118 /* AreaShapesDemoViewController.swift in Sources */,
4B0000011111111111111119 /* BuildingFloorSelectionDemoViewController.swift in Sources */,
4B000001111111111111111A /* CameraDemoViewController.swift in Sources */,
D175A3962EFB239A00F925EF /* StackedMapsDemoViewController.swift in Sources */,
D175A3972EFB239A00F925EF /* StackedMapsUtils.swift in Sources */,
D175A3982EFB239A00F925EF /* MultiFloorViewDemoViewController.swift in Sources */,
4B000001111111111111111B /* Image3DDemoViewController.swift in Sources */,
4B000001111111111111111C /* InteractivityDemoViewController.swift in Sources */,
4B000001111111111111111D /* LabelsDemoViewController.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import UIKit
import Mappedin

final class MultiFloorViewDemoViewController: UIViewController {
private let mapView = MapView()
private let loadingIndicator = UIActivityIndicatorView(style: .large)

override func viewDidLoad() {
super.viewDidLoad()
title = "Multi-Floor View"
view.backgroundColor = .systemBackground

let container = mapView.view
container.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(container)

// Add loading indicator
loadingIndicator.translatesAutoresizingMaskIntoConstraints = false
loadingIndicator.startAnimating()
view.addSubview(loadingIndicator)

NSLayoutConstraint.activate([
container.leadingAnchor.constraint(equalTo: view.leadingAnchor),
container.trailingAnchor.constraint(equalTo: view.trailingAnchor),
container.topAnchor.constraint(equalTo: view.topAnchor),
container.bottomAnchor.constraint(equalTo: view.bottomAnchor),

loadingIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor),
loadingIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor),
])

// See Trial API key Terms and Conditions
// https://developer.mappedin.com/docs/demo-keys-and-maps
let options = GetMapDataWithCredentialsOptions(
key: "mik_yeBk0Vf0nNJtpesfu560e07e5",
secret: "mis_2g9ST8ZcSFb5R9fPnsvYhrX3RyRwPtDGbMGweCYKEq385431022",
mapId: "67a6641530e940000bac3c1a"
)

// Load the map data.
mapView.getMapData(options: options) { [weak self] r in
guard let self = self else { return }
if case .success = r {
print("getMapData success")

// Display the map with multi-floor view enabled.
let show3dMapOptions = Show3DMapOptions(
multiFloorView: Show3DMapOptions.MultiFloorViewOptions(
enabled: true,
//TODO remove commented code after fix released.
// floorGap: 10.0,
// updateCameraElevationOnFloorChange: true
)
)

self.mapView.show3dMap(options: show3dMapOptions) { r2 in
if case .success = r2 {
DispatchQueue.main.async {
self.loadingIndicator.stopAnimating()
}
self.onMapReady()
} else if case .failure(let error) = r2 {
DispatchQueue.main.async {
self.loadingIndicator.stopAnimating()
}
print("show3dMap error: \(error)")
}
}
} else if case .failure(let error) = r {
print("getMapData error: \(error)")
}
}
}

// Place your code to be called when the map is ready here.
private func onMapReady() {
print("show3dMap success - Map displayed with multi-floor view")

// Get all floors and find the ones we need.
mapView.mapData.getByType(MapDataType.floor) { [weak self] (result: Result<[Floor], Error>) in
guard let self = self else { return }
switch result {
case .success(let floors):
// Set the current floor to the one with elevation 9.
if let floor9 = floors.first(where: { $0.elevation == 9.0 }) {
self.mapView.setFloor(floorId: floor9.id) { _ in
print("Set floor to elevation 9: \(floor9.name)")
}
}

// Show the 6th floor (elevation 6) as well.
if let floor6 = floors.first(where: { $0.elevation == 6.0 }) {
self.mapView.updateState(
floor: floor6,
state: FloorUpdateState(
geometry: FloorUpdateState.Geometry(visible: true)
)
) { _ in
print("Made floor with elevation 6 visible: \(floor6.name)")
}
}
case .failure(let error):
print("Failed to get floors: \(error)")
}
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
import UIKit
import Mappedin

final class StackedMapsDemoViewController: UIViewController {
private let mapView = MapView()
private let loadingIndicator = UIActivityIndicatorView(style: .large)

private var animate = true
private var distanceBetweenFloors: Double = 10.0
private var gapValueLabel: UILabel!

override func viewDidLoad() {
super.viewDidLoad()
title = "Stacked Maps"
view.backgroundColor = .systemBackground

let container = mapView.view
container.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(container)

// Add loading indicator
loadingIndicator.translatesAutoresizingMaskIntoConstraints = false
loadingIndicator.startAnimating()
view.addSubview(loadingIndicator)

// Add control panel
let controlPanel = createControlPanel()
controlPanel.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(controlPanel)

NSLayoutConstraint.activate([
container.leadingAnchor.constraint(equalTo: view.leadingAnchor),
container.trailingAnchor.constraint(equalTo: view.trailingAnchor),
container.topAnchor.constraint(equalTo: view.topAnchor),
container.bottomAnchor.constraint(equalTo: view.bottomAnchor),

loadingIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor),
loadingIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor),

controlPanel.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 16),
controlPanel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 16),
])

// See Trial API key Terms and Conditions
// https://developer.mappedin.com/docs/demo-keys-and-maps
let options = GetMapDataWithCredentialsOptions(
key: "mik_yeBk0Vf0nNJtpesfu560e07e5",
secret: "mis_2g9ST8ZcSFb5R9fPnsvYhrX3RyRwPtDGbMGweCYKEq385431022",
mapId: "666ca6a48dd908000bf47803"
)

// Load the map data.
mapView.getMapData(options: options) { [weak self] r in
guard let self = self else { return }
if case .success = r {
print("getMapData success")

// Display the map with higher pitch for better stacked view.
let show3dMapOptions = Show3DMapOptions(
pitch: 80.0
)

self.mapView.show3dMap(options: show3dMapOptions) { r2 in
if case .success = r2 {
DispatchQueue.main.async {
self.loadingIndicator.stopAnimating()
}
self.onMapReady()
} else if case .failure(let error) = r2 {
DispatchQueue.main.async {
self.loadingIndicator.stopAnimating()
}
print("show3dMap error: \(error)")
}
}
} else if case .failure(let error) = r {
print("getMapData error: \(error)")
}
}
}

private func createControlPanel() -> UIView {
let panel = UIVisualEffectView(effect: UIBlurEffect(style: .systemMaterial))
panel.layer.cornerRadius = 12
panel.clipsToBounds = true

let stackView = UIStackView()
stackView.axis = .vertical
stackView.spacing = 12
stackView.translatesAutoresizingMaskIntoConstraints = false
panel.contentView.addSubview(stackView)

NSLayoutConstraint.activate([
stackView.leadingAnchor.constraint(equalTo: panel.contentView.leadingAnchor, constant: 16),
stackView.trailingAnchor.constraint(equalTo: panel.contentView.trailingAnchor, constant: -16),
stackView.topAnchor.constraint(equalTo: panel.contentView.topAnchor, constant: 16),
stackView.bottomAnchor.constraint(equalTo: panel.contentView.bottomAnchor, constant: -16),
])

// Expand button
let expandButton = UIButton(type: .system)
expandButton.setTitle("Expand", for: .normal)
expandButton.titleLabel?.font = UIFont.systemFont(ofSize: 16, weight: .medium)
expandButton.addTarget(self, action: #selector(expandTapped), for: .touchUpInside)
stackView.addArrangedSubview(expandButton)

// Collapse button
let collapseButton = UIButton(type: .system)
collapseButton.setTitle("Collapse", for: .normal)
collapseButton.titleLabel?.font = UIFont.systemFont(ofSize: 16, weight: .medium)
collapseButton.addTarget(self, action: #selector(collapseTapped), for: .touchUpInside)
stackView.addArrangedSubview(collapseButton)

// Animate toggle
let animateStack = UIStackView()
animateStack.axis = .horizontal
animateStack.spacing = 8

let animateLabel = UILabel()
animateLabel.text = "Animate"
animateLabel.font = UIFont.systemFont(ofSize: 14)

let animateSwitch = UISwitch()
animateSwitch.isOn = animate
animateSwitch.addTarget(self, action: #selector(animateToggled(_:)), for: .valueChanged)

animateStack.addArrangedSubview(animateLabel)
animateStack.addArrangedSubview(animateSwitch)
stackView.addArrangedSubview(animateStack)

// Floor gap label
let floorGapLabel = UILabel()
floorGapLabel.text = "Floor Gap:"
floorGapLabel.font = UIFont.systemFont(ofSize: 14)
stackView.addArrangedSubview(floorGapLabel)

// Floor gap slider
let slider = UISlider()
slider.minimumValue = 0
slider.maximumValue = 50
slider.value = Float(distanceBetweenFloors)
slider.addTarget(self, action: #selector(sliderChanged(_:)), for: .valueChanged)
stackView.addArrangedSubview(slider)

// Gap value display
gapValueLabel = UILabel()
gapValueLabel.text = "\(Int(distanceBetweenFloors))m"
gapValueLabel.font = UIFont.systemFont(ofSize: 14)
gapValueLabel.textAlignment = .center
stackView.addArrangedSubview(gapValueLabel)

return panel
}

@objc private func expandTapped() {
StackedMapsUtils.expandFloors(
mapView: mapView,
options: ExpandOptions(
distanceBetweenFloors: distanceBetweenFloors,
animate: animate
)
)
}

@objc private func collapseTapped() {
StackedMapsUtils.collapseFloors(
mapView: mapView,
options: CollapseOptions(animate: animate)
)
}

@objc private func animateToggled(_ sender: UISwitch) {
animate = sender.isOn
}

@objc private func sliderChanged(_ sender: UISlider) {
distanceBetweenFloors = Double(sender.value)
gapValueLabel.text = "\(Int(distanceBetweenFloors))m"

// Automatically expand floors with new gap value
StackedMapsUtils.expandFloors(
mapView: mapView,
options: ExpandOptions(
distanceBetweenFloors: distanceBetweenFloors,
animate: animate
)
)
}

// Place your code to be called when the map is ready here.
private func onMapReady() {
print("show3dMap success - Map displayed")

// Hide the outdoor map and configure camera for stacked view.
mapView.outdoor.hide()
mapView.camera.setMaxPitch(88.0)
mapView.camera.set(
target: CameraTarget(pitch: 75.0)
)
}
}

Loading