Crash when wrapping latitude and longitude in map - mapkit
I get the current user map location and present it on a map with his location as the center of map.
It crash on the line
let currentLatitude = (locationManager.location?.coordinate.latitude)!
let currentLongitude = (locationManager.location?.coordinate.longitude)!
with the error "Could not inset legal attribution from corner 4"
I think its something related to the force wrap for latitude and longitude. What shall i do to fix this error??
Here is my code:
// Location Manager settings
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
let currentLatitude = (locationManager.location?.coordinate.latitude)!
let currentLongitude = (locationManager.location?.coordinate.longitude)!
//Map settings
mapMyLocation.showsUserLocation = true
mapMyLocation.delegate = self
let locationcoordinates = CLLocationCoordinate2D(latitude: currentLatitude, longitude: currentLongitude)
let zoomSpan = MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)
let region = MKCoordinateRegion(center: locationcoordinates, span: zoomSpan)
mapMyLocation.setRegion(region, animated: true)
Try the following code
if let currentLatitude = locationManager.location?.coordinate.latitude,
let currentLongitude = locationManager.location?.coordinate.longitude {
//Map settings
mapMyLocation.showsUserLocation = true
mapMyLocation.delegate = self
let locationcoordinates = CLLocationCoordinate2D(latitude: currentLatitude, longitude: currentLongitude)
let zoomSpan = MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)
let region = MKCoordinateRegion(center: locationcoordinates, span: zoomSpan)
mapMyLocation.setRegion(region, animated: true)
}
Related
How to stop UICollectionViewDiffableDataSource to scroll the collection view while apply snapshot?
I have a UICollectionViewDiffableDataSource for vertical scrolling, with dynamic height cells. Every time I call 'apply' on the datasource the collection view scrolls a bit and it doesn't look good. How do I prevent it from scrolling? private func applySnapshot(completion: #escaping () -> ()) { let sections = presenter.getSections().filter({$0.date != nil} ).map({$0.date!}) var snapshot = Snapshot() snapshot.appendSections(sections) sections.forEach { (date) in if var events = presenter.getEvents(by: date) { if events.isEmpty { events = [Event(emptyEventDate: date)] } snapshot.appendItems(events, toSection: date) } } self.dataSource.apply(snapshot, animatingDifferences: false) { completion() } } private func createLayout() -> UICollectionViewLayout { let kHeaderHeight: CGFloat = 25 let kSectionInsetTop: CGFloat = 8 let kSectionInsetLeadingTrailing: CGFloat = 15 let kSectionInsetBottom: CGFloat = 28 let kItemSpacing: CGFloat = 12 let estimatedHeight = CGFloat(400) let layoutSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(estimatedHeight)) let item = NSCollectionLayoutItem(layoutSize: layoutSize) let group = NSCollectionLayoutGroup.horizontal(layoutSize: layoutSize, subitem: item, count: 1) group.contentInsets = NSDirectionalEdgeInsets( top: 0, leading: kSectionInsetLeadingTrailing, bottom: 0, trailing: kSectionInsetLeadingTrailing) let section = NSCollectionLayoutSection(group: group) section.contentInsets = NSDirectionalEdgeInsets( top: kSectionInsetTop, leading: 0, bottom: kSectionInsetBottom, trailing: 0) section.interGroupSpacing = kItemSpacing let headerSize = NSCollectionLayoutSize( widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(kHeaderHeight) ) let sectionHeader = NSCollectionLayoutBoundarySupplementaryItem( layoutSize: headerSize, elementKind: UICollectionView.elementKindSectionHeader, alignment: .top ) sectionHeader.pinToVisibleBounds = true section.boundarySupplementaryItems = [sectionHeader] let layout = UICollectionViewCompositionalLayout(section: section) return layout } I appreciate your help 🙏🏻 Edit: I see that the view "jumps"/scrolls a bit when I insert a new item/section before the visible cells. If I insert after it doesn't happen.
go to a SwiftUI view by tapping a pin annotation
I want to go to new SwiftUI View by tapping a pin annotation I have made a mapView and pin annotation on it I want to go to a SwiftUI view by Tapping on this pin how can I go to SwiftUi view in Uiviewrepresentable View this is my mapView func updateUIView(_ view: MKMapView, context: Context) { let locationManager = CLLocationManager() let path = Datas.path var locationsDic: [[String: Any]] = [["latitude": 0, "longitude": 0],["latitude": 0, "longitude": 0],["latitude": 0, "longitude": 0]] view.showsUserLocation = true locationManager.requestAlwaysAuthorization() locationManager.requestWhenInUseAuthorization() if CLLocationManager.locationServicesEnabled() { locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters locationManager.startUpdatingLocation() DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: { let locValue:CLLocationCoordinate2D = locationManager.location!.coordinate let coordinate = CLLocationCoordinate2D( latitude: locValue.latitude, longitude: locValue.longitude) locationsDic[0]["latitude"] = locValue.latitude.advanced(by: 0.0) locationsDic[0]["longitude"] = locValue.longitude.advanced(by: 0.0) (locationsDic as NSArray).write(toFile: path, atomically: true) let span = MKCoordinateSpan(latitudeDelta: 0.02, longitudeDelta: 0.02) let region = MKCoordinateRegion(center: coordinate, span: span) view.setRegion(region, animated: true) let originAnnotation = MKPointAnnotation() originAnnotation.title = "origin" originAnnotation.coordinate = CLLocationCoordinate2D(latitude: 37.332072300, longitude: -122.011138100) view.addAnnotation(originAnnotation) }) } locationsDic = NSArray(contentsOfFile: path) as! [[String: Any]]}}
Apple Maps Not Showing Map Overlay
I have a question regarding creating a Apple Map Overlay. I am trying to set on odd shape overlay from a JSON file. I have researched this on Stack Overflow, and have tried many of the solutions, but none seem to work. My code is below: import UIKit import MapKit import CoreLocation class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate, UIGestureRecognizerDelegate { #IBOutlet weak var mapView: MKMapView! var coordinate: CLLocationCoordinate2D? override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. mapView.showsUserLocation = true mapView.delegate = self mapView.mapType = .standard let gestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.TapGesture)) mapView.addGestureRecognizer(gestureRecognizer) } func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer { if overlay is MKPolygon { let polygonView = MKPolygonRenderer(overlay: overlay) polygonView.strokeColor = UIColor.black polygonView.lineWidth = 0.5 polygonView.fillColor = UIColor.blue return polygonView } return MKOverlayRenderer() } #objc func TapGesture(gesRect: UITapGestureRecognizer) { let location = gesRect.location(in: mapView) coordinate = mapView.convert(location,toCoordinateFrom: mapView) let locCoord = mapView.convert(location, toCoordinateFrom: mapView) print("Tapped at lat: \(locCoord.latitude) long: \(locCoord.longitude)") print("Tapped at: \(location)") self.retreiveShape() { (full_shape) in if let shape = full_shape { let polygon = MKPolygon.init(coordinates: shape, count: shape.count) self.mapView.addOverlay(polygon) } else { print("ARRAY EMPTY") } } } func retreiveShape(completion: #escaping ([CLLocationCoordinate2D]?) -> ()) { let path = Bundle.main.path(forResource: "shape", ofType: "json") var coord_array = [CLLocationCoordinate2D]() do { let data = try Data.init(contentsOf: URL.init(fileURLWithPath: path!)) let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) if let dictionary = json as? [String: Any] { if let shape = dictionary["shape"] as? Array<Any> { for regions in shape { guard let region = regions as? Array<Array<Array<Double>>> else { print("NOT HAPPENING") return } for sections in region { for coord in sections { print("LATITUDE: \(coord[0])", "LONGITUDE: \(coord[1])") let coordinatesToAppend = CLLocationCoordinate2D(latitude: coord[0], longitude: coord[1]) coord_array.append(coordinatesToAppend) } } } completion(coord_array) } } } catch let error { print(error) } } The shape.json file is below: { "shape":[ [ [ [-81.621199, 30.282314], [-81.613987, 30.281941], [-81.611277, 30.284743], [-81.602735, 30.284026], [-81.601978, 30.292561], [-81.596275, 30.290861], [-81.592406, 30.290182], [-81.571146, 30.28763], [-81.55922, 30.286602], [-81.559148, 30.291132], [-81.558633, 30.294747], [-81.55881, 30.312887], [-81.558601, 30.312888], [-81.558622, 30.316235], [-81.558313, 30.316828], [-81.552252, 30.320252], [-81.548471, 30.321618], [-81.527882, 30.323989], [-81.529486, 30.328076], [-81.537635, 30.336704], [-81.537706, 30.337221], [-81.538717, 30.338277], [-81.539343, 30.338462], [-81.542809, 30.341686], [-81.547286, 30.345211], [-81.552498, 30.348839], [-81.552559, 30.352445], [-81.577566, 30.352039], [-81.578098, 30.353324], [-81.578161, 30.35642], [-81.577294, 30.3596], [-81.576996, 30.366609], [-81.58011, 30.366553], [-81.580875, 30.37062], [-81.580844, 30.373862], [-81.581462, 30.374486], [-81.578114, 30.374236], [-81.572908, 30.374611], [-81.562232, 30.372303], [-81.551965, 30.366559], [-81.548676, 30.365568], [-81.540187, 30.378172], [-81.538175, 30.380467], [-81.538213, 30.387239], [-81.536613, 30.388739], [-81.512612, 30.392739], [-81.505211, 30.390739], [-81.490911, 30.392139], [-81.49085, 30.389014], [-81.489978, 30.389207], [-81.488818, 30.38775], [-81.489203, 30.389266], [-81.487056, 30.390019], [-81.481446, 30.391262], [-81.479505, 30.39117], [-81.477708, 30.390635], [-81.476792, 30.390609], [-81.476244, 30.391002], [-81.473212, 30.389422], [-81.472125, 30.388436], [-81.472225, 30.388071], [-81.474072, 30.386758], [-81.475085, 30.384287], [-81.474394, 30.381898], [-81.473246, 30.38059], [-81.473337, 30.380112], [-81.47295, 30.379864], [-81.472643, 30.380053], [-81.471914, 30.379532], [-81.471629, 30.378346], [-81.470845, 30.377256], [-81.468671, 30.376016], [-81.466871, 30.374481], [-81.465402, 30.374424], [-81.464374, 30.373764], [-81.465116, 30.373015], [-81.467728, 30.372493], [-81.469102, 30.371435], [-81.470279, 30.369931], [-81.472008, 30.370608], [-81.473695, 30.370041], [-81.471862, 30.370238], [-81.470952, 30.369737], [-81.471715, 30.369462], [-81.470506, 30.369378], [-81.469456, 30.368207], [-81.468051, 30.367707], [-81.46754, 30.366828], [-81.466905, 30.366464], [-81.467432, 30.366219], [-81.466928, 30.365735], [-81.465222, 30.365136], [-81.464909, 30.364103], [-81.46316, 30.362764], [-81.463369, 30.36188], [-81.462197, 30.361235], [-81.461151, 30.36123], [-81.46117, 30.360531], [-81.461878, 30.360305], [-81.461619, 30.359642], [-81.461873, 30.358669], [-81.461645, 30.358376], [-81.460504, 30.358329], [-81.46288, 30.357969], [-81.462786, 30.357137], [-81.461247, 30.355282], [-81.460556, 30.352518], [-81.46184, 30.340222], [-81.462497, 30.339325], [-81.465064, 30.337897], [-81.471588, 30.328301], [-81.472988, 30.318258], [-81.469123, 30.319481], [-81.450496, 30.320896], [-81.443818, 30.302908], [-81.442451, 30.301512], [-81.438991, 30.299798], [-81.437921, 30.298031], [-81.437696, 30.284657], [-81.438134, 30.283427], [-81.439935, 30.281191], [-81.440578, 30.279729], [-81.440309, 30.276152], [-81.441217, 30.271746], [-81.440891, 30.270368], [-81.440247, 30.269313], [-81.438555, 30.267721], [-81.43765, 30.266188], [-81.43705, 30.257116], [-81.441869, 30.256519], [-81.45385, 30.252008], [-81.466184, 30.251073], [-81.472173, 30.251296], [-81.491372, 30.251034], [-81.507105, 30.253603], [-81.510744, 30.253761], [-81.530261, 30.250144], [-81.56957, 30.249854], [-81.584658, 30.251369], [-81.586895, 30.251326], [-81.589607, 30.250593], [-81.593308, 30.248471], [-81.605497, 30.260294], [-81.621493, 30.282334], [-81.621199, 30.282314] ] ] ] } It should create an odd shape overlay in the Southside of Jacksonville,FL, but it isn't. When the completion block is called the Coordinates are added to the array, but the map overlay isn't showing. Any thoughts?
Well this is somewhat embarrassing. I did as was suggested in the comments, and tried having the shape with nine vertices. It still didn't work. I then changed the coord from: print("LATITUDE: \(coord[0])", "LONGITUDE: \(coord[1])") let coordinatesToAppend = CLLocationCoordinate2D(latitude: coord[0], longitude: coord[1]) to: print("LATITUDE: \(coord[1])", "LONGITUDE: \(coord[0])") let coordinatesToAppend = CLLocationCoordinate2D(latitude: coord[1], longitude: coord[0]) It works perfectly. Turns out I had the Latitude and Longitude wrong.
AVMutableVideoComposition sometimes won't play video
I'm using this short snippet to set up my video. For some unknown reason - sometimes the video simply won't show up, while for other video it'll work perfectly. let videoTrack: AVAssetTrack = asset.tracksWithMediaType(AVMediaTypeVideo)[0] let composition: AVMutableComposition = AVMutableComposition() let videoComposition: AVMutableVideoComposition = AVMutableVideoComposition() var videoSize: CGSize = videoTrack.naturalSize let isPortrait_: Bool = self.isVideoPortrait(asset) if isPortrait_ { NSLog("video is portrait ") videoSize = CGSizeMake(videoSize.height, videoSize.width) } composition.naturalSize = videoSize videoComposition.renderSize = videoSize // videoComposition.renderSize = videoTrack.naturalSize; // videoComposition.frameDuration = CMTimeMake(1, 30) let compositionVideoTrack = composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: 1) let timeRange = videoTrack.timeRange do { try compositionVideoTrack.insertTimeRange(timeRange, ofTrack: videoTrack, atTime: kCMTimeZero) } catch { print("error") } let layerInst = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack) layerInst.setTransform(videoTrack.preferredTransform, atTime: kCMTimeZero) let inst: AVMutableVideoCompositionInstruction = AVMutableVideoCompositionInstruction() inst.timeRange = timeRange inst.layerInstructions = [layerInst] videoComposition.instructions = [inst] let playerItem = AVPlayerItem(asset: composition) playerItem.videoComposition = videoComposition Tho for some videos, it simply wont show them up. Any suggestions? Thanks!!
Hello i had a relative similar code hope this helps you figure out your problem class func MergeVideosSequentially(URLS : [NSURL], callback : (error : ErrorType? , outURL : NSURL?) -> Void){ let composition = AVMutableComposition() //videoTrack let videoTrack = composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid) let audioTrack = composition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid) var cursorTime = kCMTimeZero for URL in URLS { let asset = AVAsset(URL: URL) let assetVideoTrack = asset.tracksWithMediaType(AVMediaTypeVideo).first! as AVAssetTrack let assetAudioTrack = asset.tracksWithMediaType(AVMediaTypeAudio).first! as AVAssetTrack var duration : CMTimeRange? = nil duration = CMTimeRangeMake(kCMTimeZero, asset.duration) do { try videoTrack.insertTimeRange(duration!, ofTrack: assetVideoTrack, atTime: cursorTime) try audioTrack.insertTimeRange(duration!, ofTrack: assetAudioTrack, atTime: cursorTime) }catch { print(error) } cursorTime = CMTimeAdd(cursorTime, asset.duration) } let directory = NSTemporaryDirectory() let dateFormatter = NSDateFormatter() dateFormatter.dateStyle = .LongStyle dateFormatter.timeStyle = .ShortStyle let date = dateFormatter.stringFromDate(NSDate()) let savePath = "\(directory)/mergedVideo-\(date).mp4" let url = NSURL(fileURLWithPath: savePath) let exporter = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetHighestQuality) exporter!.outputURL = url exporter!.shouldOptimizeForNetworkUse = true exporter!.outputFileType = AVFileTypeMPEG4 exporter!.exportAsynchronouslyWithCompletionHandler({ () -> Void in let outputURL = exporter!.outputURL switch exporter!.status { case .Completed : dispatch_async(dispatch_get_main_queue(), { () -> Void in callback(error: nil, outURL: outputURL) }) default: callback(error: CCMovieWriterError.CannotMergeClips, outURL: nil) } }) }
Set the bounds of a mapView
I have an app that calls an api and returns a list of locations. Once the data is returned, I convert the JSON to map points for annotations. These get added to the ma with no problem. The problem I am running into is setting the bounds of the map. I can't seem to figure it out. The code I currently have is. _handleResponse(response) { var locations = []; // Loop through repsone and add items to an arra for annotations for (var i = 0; i < response.length; i++) { // Get the location var location = response[i]; // Parse the co ords var lat = parseFloat(location.Latitude); var lng = parseFloat(location.Longitude); // Add the location to array locations.push({ latitude: lat, longitude: lng, title: location.Name }); } // This calls the map set state this.setState({ annotations: locations }); } and here is my view code <View style={styles.container}> <MapView style={styles.map} onRegionChangeComplete={this._onRegionChangeComplete} annotations={this.state.annotations} /> </View>
You'll want <MapView ... region={region} /> where var region = { latitude, longitude, latitudeDelta, longitudeDelta, }; latitude and longitude are the center of the map and the deltas are the distance (in degrees) between the minimum and maximum lat/long shown. For instance, given a certain radius in miles around a point and an aspect ratio of the map view, you could calculate region as follows: var radiusInRad = radiusInKM / earthRadiusInKM; var longitudeDelta = rad2deg(radiusInRad / Math.cos(deg2rad(latitude))); var latitudeDelta = aspectRatio * rad2deg(radiusInRad); The definitions of rad2deg, deg2rad, and earthRadiusInKM are left as an exercise to the reader.
Here is my complete code based on #Philipp's answer: import React, { Component } from 'react'; import { MapView } from 'react-native'; const earthRadiusInKM = 6371; // you can customize these two values based on your needs const radiusInKM = 1; const aspectRatio = 1; class Map extends Component { constructor(props) { super(props); // this will be the map's initial region this.state = { region : { latitude: 0, longitude: 0 } }; } // you need to invoke this method to update your map's region. showRegion(locationCoords) { if (locationCoords && locationCoords.latitude && locationCoords.longitude) { var radiusInRad = radiusInKM / earthRadiusInKM; var longitudeDelta = this.rad2deg(radiusInRad / Math.cos(this.deg2rad(locationCoords.latitude))); var latitudeDelta = aspectRatio * this.rad2deg(radiusInRad); this.setState({ region: { latitude: locationCoords.latitude, longitude: locationCoords.longitude, latitudeDelta: latitudeDelta, longitudeDelta: longitudeDelta } }); } } render () { return ( <MapView style={{flex: 1}} region={this.state.region}/> ) } deg2rad (angle) { return angle * 0.017453292519943295 // (angle / 180) * Math.PI; } rad2deg (angle) { return angle * 57.29577951308232 // angle / Math.PI * 180 } }