I do a JSON Request and get some information.
func parseJSON(poiData: Data) {
let decoder = JSONDecoder()
do {
let decodedData = try decoder.decode(POIData.self, from: poiData)
POIManager.POIname_One = decodedData.results[0].name
POIManager.POIplaceid_One = decodedData.results[4].place_id
POIManager.POIvicinity_One = decodedData.results[4].vicinity
POIManager.POIlong_One = decodedData.results[0].geometry.location.lat
POIManager.POIlat_One = decodedData.results[0].geometry.location.lng
POIManager.POIname_Two = decodedData.results[1].name
POIManager.POIplaceid_Two = decodedData.results[1].place_id
POIManager.POIvicinity_Two = decodedData.results[1].vicinity
POIManager.POIlong_Two = decodedData.results[1].geometry.location.lat
POIManager.POIlat_Two = decodedData.results[1].geometry.location.lng
POIManager.POIname_Three = decodedData.results[2].name
POIManager.POIplaceid_Three = decodedData.results[2].place_id
POIManager.POIvicinity_Three = decodedData.results[2].vicinity
POIManager.POIlong_Three = decodedData.results[2].geometry.location.lat
POIManager.POIlat_Three = decodedData.results[2].geometry.location.lng
} catch {
print(error)
}
}
In a different Swift file it put the results from the request in a list like this:
#IBAction func kategorieEins(_ sender: UIButton) {
//Eigene Standort soll hier gezeigt werden/aktualisierter Standort
locationManager.delegate=self
let marker1 = GMSMarker()
marker1.position = CLLocationCoordinate2D(latitude: POIManager.POIlong_One, longitude: POIManager.POIlat_One)
marker1.title = POIManager.POIname_One
marker1.snippet = "Marker1_0"
marker1.map = mapView
let marker2 = GMSMarker()
marker2.position = CLLocationCoordinate2D(latitude: POIManager.POIlong_Two, longitude: POIManager.POIlat_Two)
marker2.title = POIManager.POIname_Two
marker2.snippet = "Marker2_0"
marker2.map = mapView
let marker3 = GMSMarker()
marker3.position = CLLocationCoordinate2D(latitude: POIManager.POIlong_Three, longitude: POIManager.POIlat_Three)
marker3.title = POIManager.POIname_Three
marker3.snippet = "Marker3_0"
marker3.map = mapView
}
As you can see this whole thing is not dynamic it is static. I write down how many markers i want to have created.
Is there a way to do this automatically? Especially when I dont know how much information there is in the json file and how many markers should be created.
I solved it now.
I tried:
decodedData.results.forEach {
print($0.name)
print($0.place_id)
}
Related
I want to show path in google map. But i am unable to show my path. Please help me . This is my code. I am try lot of time in swift. Any help would be appreciated. Thanks in advance.
let camera = GMSCameraPosition.camera(withLatitude: 48.4843822562792, longitude: 35.0635632500052, zoom: 6)
let mapView = GMSMapView.map(withFrame: .zero, camera: camera)
self.view = mapView
let manager = AFHTTPSessionManager()
manager.requestSerializer = AFJSONRequestSerializer()
manager.responseSerializer.acceptableContentTypes = nil
let urlString = "https://maps.googleapis.com/maps/api/directions/json?origin=48.4843822562792,35.0635632500052&destination=48.4893899423081,35.0640017911792&waypoints=48.4833428800255,35.0710221379995|48.4887622031403,35.0573639944196&key=AIzaSyDvS9TbaQ1WzP_3YX6TBrjoTNGhnFa0MBY"
let urlwithPercentEscapes = urlString.addingPercentEncoding( withAllowedCharacters: .urlQueryAllowed)
manager.get(urlwithPercentEscapes!, parameters: nil, success: { (operation, response) in
let parsedData = JSON(response)
var path = GMSPath.init(fromEncodedPath: parsedData["routes"][0]["overview_polyline"]["points"].string!)
//GMSPath.fromEncodedPath(parsedData["routes"][0]["overview_polyline"]["points"].string!)
print(path!)
var singleLine = GMSPolyline.init(path: path)
singleLine.strokeWidth = 7
singleLine.strokeColor = UIColor.green
singleLine.map = self.mapView
}, failure: { (operation, error) in
})
I tried to implement differents solutions for draw polyLines between markers on my GMSMapView but is not working. Do you have others solutions or maybe do you know what's wrong in my code ?
override func viewDidLoad() {
super.viewDidLoad()
let path = GMSMutablePath()
_data = _modelDelivery.getGarageFromDeliver(refDelivery: _delivery._ref)
let camera = GMSCameraPosition.camera(withLatitude: 48.853183, longitude: 2.369144, zoom: 13.0)
self._mapView.camera = camera
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: 48.8531827, longitude: 2.3691443000000163)
path.add(marker.position)
marker.title = "Ma position"
marker.icon = GMSMarker.markerImage(with: UIColor.blue)
marker.map = self._mapView
for elem in _data {
let address = elem._adress + ", " + elem._city + ", " + String(elem._zipCode) + ", France"
let geocoder = CLGeocoder()
geocoder.geocodeAddressString(address) {
placemarks, error in
let placemark = placemarks?.first
let lat = placemark?.location?.coordinate.latitude
let lon = placemark?.location?.coordinate.longitude
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: lat!, longitude: lon!)
path.add(marker.position)
marker.title = elem._nameOfGarage
marker.snippet = elem._adress + "\nOrdre de passege : "
marker.map = self._mapView
}
}
let rectangle = GMSPolyline(path: path)
rectangle.strokeWidth = 4
rectangle.strokeColor = UIColor.red
rectangle.map = self._mapView
}
I believe you have configured everything fine in https://console.developers.google.com.
We can draw a polyline between two coordinates. You need to create your ServerKey on https://console.developers.google.com where you have created your project for GoogleMaps and then use that Server Key in the URL below.
This draws polyline between two coordinates.
func drawPath() {
//Taken two source and destinations coordinates. Take the coordinates in this way. "Lat,Long" in a String
let sourceString = "28.6562,77.2410"
let destinationString = "27.1750,78.0422"
//GoogleMaps Web API to draw the polyline
let combinedUrl : String = "https://maps.googleapis.com/maps/api/directions/json?" + "origin=\(sourceString)&destination=\(destinationString)&key=YOUR_SERVER_KEY"
let url = URL(string:combinedUrl)
let task = URLSession.shared.dataTask(with: url!) { (data:Data?, response:URLResponse?, error:Error?) in
if error != nil {
print(error.debugDescription)
return
}
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! NSDictionary
//We need to get to the points key in overview_polyline object in order to pass the points to GMSPath.
let route = (((json.object(forKey: "routes") as! NSArray).object(at: 0) as! NSDictionary).object(forKey: "overview_polyline") as! NSDictionary).value(forKey: "points") as! String
//Draw on main thread always else it will crash
DispatchQueue.main.async {
let path = GMSPath(fromEncodedPath:route)!
let polyline = GMSPolyline(path: path)
polyline.strokeColor = UIColor.green
polyline.strokeWidth = 5.0
//mapView is your GoogleMaps Object i.e. _mapView in your case
polyline.map = self.mapView
}
} catch {
}
}
task.resume()
}
JSON points key data required.
Later on you can animate to the drawn region first coordinate using the GMSCameraPosition.
Similarly for multiple points, just pass the respective coordinates in a for loop and call drawPath function.
You can have a look at this Video Tutorial too.
I'm making the GMSPolyline in the GoogleMap. When I want to remove the GMSPolyline by coding polyline.map = nil, but it can not working for me. I'm copy some coding in the below.
(added the marker before, I need remove the polyline only)
Thank you for your help!!!
my coding:
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
//MARK: create the GMSPolyline
let polyline = GMSPolyline()
//MARK: remove the old polyline from the GoogleMap
polyline.map = nil
let origin = "\(mapView.myLocation!.coordinate.latitude),\(mapView.myLocation!.coordinate.longitude)"
let destination = "\(marker.position.latitude),\(marker.position.longitude)"
let url = "https://maps.googleapis.com/maps/api/directions/json?origin=\(origin)&destination=\(destination)&mode=driving"
Alamofire.request(url).responseJSON { response in
let json = JSON(data: response.data!)
let routes = json["routes"].arrayValue
//MARK: print route using Polyline
for route in routes
{
let routeOverviewPolyline = route["overview_polyline"].dictionary
let points = routeOverviewPolyline?["points"]?.stringValue
let path = GMSPath(fromEncodedPath: points!)
polyline = GMSPolyline(path: path)
polyline.strokeWidth = 4
polyline.strokeColor = UIColor.yellow
polyline.isTappable = true
polyline.map = self.mapView
}
}
return false
}
you should clear the map before adding new polyline on the map.
clear() function of GMSMapView
/**
Clears all markup that has been added to the map, including markers, polylines and ground overlays.
This will not clear the visible location dot or reset the current mapType.
*/
Try this
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
//MARK: create the GMSPolyline
let polyline = GMSPolyline()
//MARK: remove the old polyline from the GoogleMap
mapView.clear()
//TODO:- Redraw all marker here.
let origin = "\(mapView.myLocation!.coordinate.latitude),\(mapView.myLocation!.coordinate.longitude)"
let destination = "\(marker.position.latitude),\(marker.position.longitude)"
let url = "https://maps.googleapis.com/maps/api/directions/json?origin=\(origin)&destination=\(destination)&mode=driving"
Alamofire.request(url).responseJSON { response in
let json = JSON(data: response.data!)
let routes = json["routes"].arrayValue
//MARK: print route using Polyline
for route in routes
{
let routeOverviewPolyline = route["overview_polyline"].dictionary
let points = routeOverviewPolyline?["points"]?.stringValue
let path = GMSPath(fromEncodedPath: points!)
polyline = GMSPolyline(path: path)
polyline.strokeWidth = 4
polyline.strokeColor = UIColor.yellow
polyline.isTappable = true
polyline.map = self.mapView
}
}
return false
}
Declare polyline outside the function as a class property.
var routePolyline: GMSPolyline? = nil
Then to clear old polyline before adding new one, use-
self.routePolyline?.map = nil
This will work as expected!
for poll in mapkit.overlays {
mapkit.removeOverlay(poll)
}
var polyline: GMSPolyline?
func drawPathOnMap() {
if polyline != nil {
//remove existing the gmspoly line from your map
polyline!.map = nil
}
let points = //Your Point
let path = GMSPath(fromEncodedPath: points)
polyline = GMSPolyline(path: path)
polyline?.strokeWidth = 5.0
polyline?.strokeColor = UIColor.init(rgb: 0x7688ED)
polyline!.map = mapView
}
I get a error: "fatal error: unexpectedly found nil while unwrapping an Optional value" when I try to pass the result of the JSON into an array. I think that the problem is when I try to get the geo coordinate: lat and long into my variables.
Please can somebody help me with this issue?
The code for the passing de result of the JSON to an array is:
ViewController.swift
import UIKit
import MapKit
import Alamofire
class ViewController: UIViewController {
var artworks = [Artwork]()
#IBOutlet weak var mapView: MKMapView!
let initialLocation = CLLocation(latitude: 52.370216, longitude: 4.895168)
let regionRadius: CLLocationDistance = 6000
override func viewDidLoad() {
super.viewDidLoad()
centerMapOnLocation(initialLocation)
getData()
mapView.addAnnotations(artworks)
mapView.delegate = self
}
func getData() {
Alamofire.request(.GET , "http://kaart.amsterdam.nl/datasets/datasets-item/t/kunstwerken-in-de-openbare-ruimte/export/json").responseJSON() {
(_, _, json, _) in
println(json)
var json = JSON(json!)
if let appArray = json["features"].array {
for artObject in appArray {
let title = artObject["properties"]["titel"].string
let locationName = artObject["properties"]["titel_key"].string
let discipline = artObject["properties"]["titel_key"].string
let latitude = (artObject["geometry"]["coordinates"].string! as NSString).doubleValue
let longitude = (artObject["geometry"]["coordinates"].string! as NSString).doubleValue
let coordinate = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
var openArt1 = Artwork(title: title!, locationName: locationName!, discipline: discipline!, coordinate: coordinate)
self.artworks.append(openArt1)
self.mapView.addAnnotations(self.artworks)
}
}
}
}
func centerMapOnLocation(location: CLLocation) {
let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate, regionRadius * 2.0, regionRadius * 2.0)
mapView.setRegion(coordinateRegion, animated: true)
}
the result of the JSON looks like this:
Optional({
features = (
{
geometry = {
coordinates = (
"4.9305202013246",
"52.363277804149"
);
type = Point;
};
properties = {
adres = "";
content = "";
"content_src" = "";
"date_created" = "2015-05-16 00:07:58";
"date_modified" = "<null>";
datum = "2013-10-09 17:15:00";
email = "";
"id_2" = "";
"link_href" = "";
locatie = "POINT(4.93052020132461 52.363277804148602)";
omschrijving = "";
plaats = "";
postcode = "";
published = "";
summary = "";
"summary_type" = "";
telefoonnummer = "";
titel = "101 namen - 136602";
"titel_key" = "101_namen_136602";
title = "";
type = Kunstwerk;
updated = "";
website = "http://www.amsterdam.nl/kunstencultuur/kunst-openbare/kunst-openbare/kunstwerken/amsterdam-stadsdeel-0/dapperbuurt/101-namen-136602/";
};
artObject["geometry"]["coordinates"] is an Array of Doubles, not a String.
If you println the JSON response it could be confusing as you see the Doubles wrapped into quotes (") but it is an array of Doubles nonetheless in the JSON for the "coordinates" key.
UPDATE:
I just checked and they are Doubles:
var err: NSError?
let data = NSData(contentsOfURL: NSURL(string: "http://kaart.amsterdam.nl/datasets/datasets-item/t/kunstwerken-in-de-openbare-ruimte/export/json")!)
let json = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.allZeros, error: &err) as! [String:AnyObject]
let features = json["features"] as! [[String:AnyObject]]
let object1 = features[0]
let geo = object1["geometry"]?["coordinates"] as! [Double]
let lat = geo[0] // 4.9305202013246
let lon = geo[1] // 52.363277804149
You just have to access these values with SwiftyJSON like this in your loop:
let coo = artObject["geometry"]["coordinates"].array!
let latitude = coo[0].doubleValue
let longitude = coo[1].doubleValue
I am having some troubles with some json data. I'm making a weather app and most of the information I parsed works but the weather
this is the council output for the json data as a whole this is the section im having troubles with
the full output of json
{
base = stations;
clouds = {
all = 90;
};
cod = 200;
coord = {
lat = "39.74";
lon = "-104.98";
};
dt = 1427305893;
id = 5419384;
main = {
humidity = 84;
pressure = 1022;
temp = "274.07";
"temp_max" = "275.35";
"temp_min" = "272.15";
};
name = Denver;
rain = {
1h = "0.25";
};
snow = {
1h = "0.17";
};
sys = {
country = US;
id = 532;
message = "0.07829999999999999";
sunrise = 1427288058;
sunset = 1427332632;
type = 1;
};
visibility = 4023;
weather = (
{
description = "light rain";
icon = 10d;
id = 500;
main = Rain;
},
{
description = snow;
icon = 13d;
id = 601;
main = Snow;
},
{
description = fog;
icon = 50d;
id = 741;
main = Fog;
},
{
description = mist;
icon = 50d;
id = 701;
main = Mist;
}
);
wind = {
deg = 20;
gust = "14.9";
speed = "12.9";
};
}
i also have it print the keys
[base, id, dt, snow, main, coord, sys, wind, weather, visibility, clouds, cod, name, rain]
I tried to save it as an array but when I set the arry[0] to a string it crashes
my code for the function
func populateLabels(weatherData: NSData){
var jsonError: NSError?
let json = NSJSONSerialization.JSONObjectWithData(weatherData, options: nil, error: &jsonError) as NSDictionary
println(json)
if let city = json["name"] as? String {
CityName.text = city
}
println(json.allKeys)
if let coord = json["coord"] as? NSDictionary {
if let longi = coord["lon"] as? Double {
long.text = String(format: "%.2f", longi)
}
if let lati = coord["lat"] as? Double {
lat.text = String(format: "%.2f", lati)
}
}
if let main = json["main"] as? NSDictionary {
if let temper = main["temp"] as? Double {
temp.text = String(format: "%.2f", temper)
}
}
If anyone knows how to get to the description that would be awesome
thanks js
I got it.. thanks for the help blacksquare, larme, chirag90
if let tasks = json["weather"] as? NSArray
{
if let task = tasks[0] as? NSDictionary
{
if let taskName = task["description"] as? NSString
{
println(taskName)
}
}
}