I'm using google street view in a an iOS app I'm developing. I have a panoView set up inside the vc and it seems that when I type in certain US addresses I get a pano image for some but not for others. For the locations that I don't get an image for I instead get a grey loading screen. I go to regular google and type in that same exact address and google shows an image does exist. Why is it not working for some addresses but it does for others?
Here's an address that I do get an image for:
253 w. 125 St, New York NY 10027 -coordinates(lat: 40.809847, lon:-73.950378)
But I get a grey loading screen for address:
150 W 225 St, Bronx NY 10463 -coordinates(lat: 40.8754871, lon: -73.9137233)
I get a debugger error message of:
1.Moving near coordinate (40.8754871,-73.9137233 error: The operation couldn’t be completed. (com.google.maps.GMSPanoramaService error 0.)?.
I have already set my Scheme to Schemes>Edit Scheme>Options>AllowLocationSimulation>DefaultLocation>New York, NY, USA
What's the problem?
Btw I'm using Xcode 7.3.1
import UIKit
import GoogleMaps
class SearchController: UIViewController, GMSMapViewDelegate, GMSPanoramaViewDelegate {
#IBOutlet weak var viewStreet: UIView!
var panoView: GMSPanoramaView!
var buildingLat: CLLocationDegrees?
var buildingLon: CLLocationDegrees?
var panoramaID: String?
let placesClient = GMSPlacesClient()
func viewDidLoad() {
super.viewDidLoad()
panoView = GMSPanoramaView(frame: CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height))
panoView.delegate = self
panoView.moveNearCoordinate(CLLocationCoordinate2D(latitude: buildingLat!, longitude: buildingLon!))
viewStreet.addSubview(panoView)
viewStreet.sendSubviewToBack(panoView)
print("\nlat: \(buildingLat)\nlon: \(buildingLon)\n")
}
// MARK: - GMSPanoramaViewDelegate
func panoramaView(view: GMSPanoramaView, error: NSError, onMoveNearCoordinate coordinate: CLLocationCoordinate2D) {
print("\n1.Moving near coordinate (\(coordinate.latitude),\(coordinate.longitude) error: \(error.localizedDescription)?\n")
}
func panoramaView(view: GMSPanoramaView, error: NSError, onMoveToPanoramaID panoramaID: String) {
print("\n2.Moving to PanoID \(panoramaID) error: \(error.localizedDescription)??\n")
}
func panoramaView(view: GMSPanoramaView, didMoveToPanorama panorama: GMSPanorama?) {
print("\n3.Moved to panoramaID: \(panorama!.panoramaID) " +
"coordinates: (\(panorama!.coordinate.latitude),\(panorama!.coordinate.longitude))???\n")
self.panoramaID = panorama!.panoramaID
}
}
I fixed it myself. I simply added in a radius on the method:
moveNearCoordinate(coordinate: CLLocationCoordinate2D, radius: Uint)
//Inside my viewDidLoad on the 4th line
panoView.moveNearCoordinate(CLLocationCoordinate2D(latitude: buildingLat!, longitude: buildingLon!), radius: 100)
You can play with the radius to see what suits you best
Related
I am using Mapbox Maps iOS to create a custom 3d pucker and use that to display the user's location.
Everything seems to be working, the camera redirects to the user's location, the pucker successfully loads. However, I am having trouble setting the pucker's location to the user's location.
You can see that I am required to set the location of the pucker in the Model instance in the loadCharacter() function. But I am unsure of how to link that to the user's current location.
Please help!!!
// ViewController.swift
import UIKit
import MapboxMaps
public class ViewController: UIViewController {
internal var mapView: MapView!
internal var cameraLocationConsumer: CameraLocationConsumer!
override public func viewDidLoad() {
super.viewDidLoad()
let options = MapInitOptions(cameraOptions: CameraOptions(zoom: 16))
mapView = MapView(frame: view.bounds, mapInitOptions: options)
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(mapView)
mapView.mapboxMap.onNext(.styleLoaded) { _ in
self.loadCharacter()
}
cameraLocationConsumer = CameraLocationConsumer(mapView: mapView)
mapView.mapboxMap.onNext(.mapLoaded) { _ in
self.mapView.location.addLocationConsumer(newConsumer: self.cameraLocationConsumer)
}
}
internal func loadCharacter() {
let uri = Bundle.main.url(forResource: "race_car_model",
withExtension: "gltf")
// Instantiate the model
let myModel = Model(uri: uri,
position: [-77.150925, 39.085006],
orientation: [0, 0, 180])
// Setting an expression to scale the model based on camera zoom
let scalingExpression = Exp(.interpolate) {
Exp(.linear)
Exp(.zoom)
0
Exp(.literal) {
[256000.0, 256000.0, 256000.0]
}
4
Exp(.literal) {
[40000.0, 40000.0, 40000.0]
}
8
Exp(.literal) {
[2000.0, 2000.0, 2000.0]
}
12
Exp(.literal) {
[100.0, 100.0, 100.0]
}
16
Exp(.literal) {
[7.0, 7.0, 7.0]
}
20
Exp(.literal) {
[1.0, 1.0, 1.0]
}
}
let configuration = Puck3DConfiguration(model: myModel, modelScale: .expression(scalingExpression))
mapView.location.options.puckType = .puck3D(configuration)
}
}
// Create class which conforms to LocationConsumer, update the camera's centerCoordinate when a locationUpdate is received
public class CameraLocationConsumer: LocationConsumer {
weak var mapView: MapView?
init(mapView: MapView) {
self.mapView = mapView
}
public func locationUpdate(newLocation: Location) {
mapView?.camera.ease(
to: CameraOptions(center: newLocation.coordinate, zoom: 16, pitch: 50.0),
duration: 1.3)
}
}
Mapbox has a repo with examples of navigation use cases that you can try, including 3D puck sample.
Note that this sample uses API from Navigation SDK, which in turn uses Maps SDK API internally. Fortunately, Navigation SDK is open-sourced, you can always look at how it draws current user location here.
I want to plot a specific point on the map having the lat and lon from an api.
Program flow:
Get LAT & LON from api (done)
Ping api again via timer after every 5 seconds to get the latest location (done)
Plot location with retrieved LAT & LON on map
The issue is every code on the net has to do with 2 points, so user loc and destination loc. I cant seem to get it to work without user loc. I have however coded this to plot the location. However, with this when I touch the map, the map zooms out. Another issue is when I get another point the previous one also remains on the screen. (for testing purpose I hard coded the lat and lon but when I connect the api code that refreshes, prior points remain and the map code is the same as this. The lat and lon are passed via func parameters in createAnnotation().)
My code:
import UIKit
import MapKit
class ViewController: UIViewController, MKMapViewDelegate {
#IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self // or connect in storyboard
createAnnotation()
}
func createAnnotation(){
let annotations = MKPointAnnotation()
annotations.coordinate = CLLocationCoordinate2D(latitude: 41.87369, longitude: -87.813293)
mapView.addAnnotation(annotations)
}}
How Do I plot the coordinates properly? and then delete the prior and show the new one?.
For the "previous one also remains on the screen" problem: don't keep making a new annotation and calling addAnnotation if you don't want to keep adding new annotations. Instead, keep hold of the annotation that you add, and move it later using its coordinate property. Something like this maybe:
class ViewController: UIViewController, MKMapViewDelegate {
#IBOutlet weak var mapView: MKMapView!
var annotationForThing: MKPointAnnotation?
var coordinateOfThing: CLLocationCoordinate2D? {
didSet {
guard let newCoord = coordinateOfThing else {
if let existing = annotationForThing {
mapView.removeAnnotation(existing)
}
return
}
if let existing = annotationForThing {
existing.coordinate = coordinateOfThing
}
else {
let newAnnotation = MKPointAnnotation()
newAnnotation = coordinateOfThing
mapView.addAnnotation(newAnnotation)
annotationForThing = newAnnotation
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self // or connect in storyboard
}
I'm getting this error:
This application has been blocked by the Google Maps API. This might be because of an incorrectly registered key.
When I try to set google maps panorama street view. If I display a regular map view, it works so seems like the key is registered properly.
I followed the directions for a panorama view exactly as per google docs:
import UIKit
import GoogleMaps
class ViewController: UIViewController, GMSMapViewDelegate {
override func loadView() {
let panoView = GMSPanoramaView(frame: .zero)
self.view = panoView
panoView.moveNearCoordinate(CLLocationCoordinate2D(latitude: -33.732, longitude: 150.312))
}
}
Any ideas?
For me, the solution was that I needed to link my project in Google Cloud Platform to a billing account.
Once I did that the street view started working correctly.
The standard Google map worked fine without a billing account, which confused me initially.
You need to configure the delegate for this object. Something like:
import UIKit
import GoogleMaps
class ViewController: UIViewController, GMSMapViewDelegate {
override func loadView() {
let panoView = GMSPanoramaView(frame: .zero)
panoView.delegate = self
self.view = panoView
panoView.moveNearCoordinate(CLLocationCoordinate2D(latitude: -33.732, longitude: 150.312))
}
}
extension ViewController: GMSPanoramaViewDelegate {
func panoramaView(_ view: GMSPanoramaView, error: Error, onMoveNearCoordinate coordinate: CLLocationCoordinate2D) {
print("error: \(error.localizedDescription)")
}
}
Facing an issue using xcode v7.2.1 and the ios simulator v9.2 .
The problem i'm facing is that the map appears blank when i run the application.
The grid lines appear for a second and then it's just blank. I've tried searching for a solution but haven't found any that have worked.
import UIKit
import MapKit
class ViewController: UIViewController, MKMapViewDelegate {
#IBOutlet var map: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
//maps integration
let longitude : CLLocationDegrees = 17.486374
let latitude : CLLocationDegrees = 78.543345
let longDelta : CLLocationDegrees = 0.1
let latDelta : CLLocationDegrees = 0.1
let location : CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitude)
let span : MKCoordinateSpan = MKCoordinateSpanMake(latDelta, longDelta)
let region : MKCoordinateRegion = MKCoordinateRegionMake(location, span)
map.setRegion(region, animated: true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
it's just a picture of the simulator once the app is run.
This is what i meant when i said blank incase it wasn't clear.
Thanks in advance !
I think it's possible you may have confused your latitude and longitude values. The lat/long you have now takes you to Svalbard and Jan Mayen (a couple of remote islands in the middle of nowhere, north of Norway), but if you switch the lat and long you get Hyderabad in India.
Just Print the Value.
it might be 0,0 and your location would be on the sea.
please make sure that your location have valid location. longitude and latitude.
This case always happen when you trying to update the map on ViewDidload instead of view Didappear.
When I receive in my Bluetooth class (new) values from my device, then I call a delegate. So the Bluetooth class is running in the background.
My protocol is simple:
protocol RefreshPositionInDrive {
func changingValue(latitude: Double, longitude: Double)
}
In my UIViewController I initialize a map. When I worked at the beginning without delegates this code works fine.
func initializeMapResolution() {
let regionRadius: CLLocationDistance = 1000
let initialLocation = CLLocation(latitude: 50.910349, longitude: 8.066895)
let coordinateRegion = MKCoordinateRegionMakeWithDistance(initialLocation.coordinate,
regionRadius * 1.5, regionRadius * 1.5)
MapDrive.setRegion(coordinateRegion, animated: true)
MapDrive.delegate = self
}
My method from my protocol:
func changingValue(latitude: Double,longitude: Double) {
print("THE NEW COORDINATES \(latitude) \(longitude)")
if self.MapDrive == nil {
print("Is nil")
} else {
updateTheMap()
}
}
Output:
THE NEW COORDINATES 25.012x 16.992
Is nil
But I don't understand that. I initialize my map first. After that the changingValue is called. How can be the MapDrive nil?
I tested the code without delegates, just with some fix coordinates in my UIViewController and the annotation appears.
(I'm working the first time with delegates.)
EDIT
I was indistinctly: My MapDrive:
#IBOutlet weak var MapDrive: MKMapView!
So I can't instantiate like you mean or?
You'll want to reference a MapDrive instance to the UIViewController, your MapDrive is probably released when your function ends.
class UIViewController {
var mapDrive = MapDrive()
func initializeMapResolution() {
// Instantiate map drive, assign it to self.mapDrive
//then assign the delegate of the property on self.
self.mapDrive.delegate = self
}
}