Learn Courses My Dashboard

Array with map coordinates and color

Hi,
I am trying to modify the annotations array generated in the BusinessMap structure of M6L12 to add a column for text to represent color. If data types in an array cannot be mixed, numbers could be used to represent the colors. I tried making a new array equal to MKPointAnnotation, but could not append a column, it seems to inherit the type and dimensions of the map coordinates, and does not seem amenable to adding a column. Should I use a one dimensional array for color, and index it along with the map coordinates?
Thanks

It should be possible… Or do some post processing… Meaning you append the new column AFTER it has finished the main array so you can have a new edited array

I thought it was possible, but I was trying to conceptualize what it would look like. Is it a four column row, ie BusinessName, Lat, Long, PinColor, or is it 4 single dimension arrays indexed the same?
Thanks

well, what does it look like now? try printing out the dataArray and show us the contents (or show your JSON file if you are doing that option

Ok thanks Francis for helping me work through this.
The Georgia Vocational Rehabilitation Agency has 39 offices statewide. Here is the section of the JSON file for the Waycross office:
{
“id”:“390”,
“name” : “Waycross”,
“Counties Served”: " ",
“Address”: " 2311 Knight Avenue, Waycross, GA 31503 ",
“phone”: " ",
“coordinates”: {
“longitude” : -82.3248444,
“latitude” : 31.2038578
},
“AWTStaff”: ,
" Comments " : " "
}

The annotations array [MKPointAnnotation] prints out as 78 values numbered 0 to 77. Here is a portion:

I have not figured out how the numbers are organized, ie are all Lats listed first then Longs, or alternating. Thanks, looking forward to your insight.

the annotations are a different set of numbers/coordinates?

why do you have 39 offices but have 78 annotations?

I believe the even number entries are Latitude, odd are longitude, one set for each location.

what I can image happening is just directly modifying the “content” of the MapAnnotation

MapAnnotation(
coordinate: location.coordinate,
content: {
//do the design changes here… so maybe Text(officeLocation[index]) or something like that
Image(systemName: “pin.circle.fill”).foregroundColor(.red)
Text(location.name)
}
)

you can check this out on our SwiftUI Bento
https://learn.codewithchris.com/courses/take/swiftui-bento/lessons/22911800-swiftui-mapannotation-how-to-add-a-pin-to-a-map

Hi,
Thanks for the suggestion, however when I run that program, the simulator constantly loops through zooming in on the user location circles, and does not show the three locations listed in the array. I am using a M1 Mac Air with MacOS 11.5.2, and Xcode 12.5.1. I have read that the M1 chip can cause some strange behaviors. Any idea what is going on and how to fix it?
Thanks

Ok, this is getting stranger. I have set showUserLocation to false, and came close to having the pin color set by a variable. Commenting out the changes leaves the simulator screen entirely a light blue. Unzipping a fresh copy yields the same light blue screen.

I have taken another try at the constant zoom looping. I determined it only happens when the simulator Features menu tab Location option is set to Apple. Not sure why.

I have been able to toggle the pin color within a slightly modified version of the MapCallouts App, and am trying to adapt the technique for use in the City Sights App. As seen in the screen shot, I have tried many variations, three tries are shown. What possibly simple thing am I missing? Thanks

Hi,
I am trying to use an array to hold location name, coordinates, and pin color, but as seen below somehow the program is determining that pin color is extra information that should not be included. How is it making a (incorrect) determination of how the array will be used?

//
//  MapLocation.swift
//  MapKit-SwiftUI
//
//  Created by Francis Martin Fuerte on 3/25/21.
// Modified by Mark Bresler 8/21/21
//

import UIKit
import CoreLocation

struct MapLocation: Identifiable {
    let id = UUID()
    let name:String
    let latitude:Double
    let longitude:Double
    let pinColor:String = "green"
    var coordinate:CLLocationCoordinate2D {
        CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
    }
}

let MapLocations = [
    MapLocation(name: "Albany", latitude: 31.576950, longitude: -84.178880),
    MapLocation(name: "Athens", latitude: 33.970940, longitude: -83.365050)
]

struct Office: Identifiable {
    let id = UUID()
    let name:String
    let latitude:Double
    let longitude:Double
    let pinColor:String = "green"
    var coordinate:CLLocationCoordinate2D {
        CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
    }
}

let Offices = [
    Office(name: "Albany", latitude: 31.576950, longitude: -84.178880, pinColor:"purple"),
    Office(name: "Athens", latitude: 33.970940, longitude: -83.365050, pinColor:"green")
]

It’s because you are providing it with a color:

let pinColor:String = "green"

And since pinColor is a let value, you can’t assign it any other value in your initializer because it’s already been initialized.

If you want your MapLocation to sometimes have a green pin and other times to have a value assigned when the pin is created, you need to either create a custom initializer:

struct MapLocation: Identifiable {
    let id = UUID()
    let name:String
    let latitude:Double
    let longitude:Double
    let pinColor:String
    var coordinate:CLLocationCoordinate2D {
        CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
    }
}

extension MapLocation {
    //we put this in an extension so we don't lose the default memberwise initializer
    init(name: String, latitude: Double, longitude: Double, pinColor: String = "green") {
        self.name = name
        self.latitude = latitude
        self.longitude = longitude
        self.pinColor = pinColor
    }
}

Or you can make pinColor a var value:

var pinColor: String = "green"

and then it will be available in the memberwise initializer.

Using an extension is an interesting idea, however I have not gotten it to work. The error message on the (init)… line is
'Invalid redeclaration of synthesized memberwise ‘init(name:latitude:longitude:pinColor:)’

///
import UIKit
import CoreLocation

struct MapLocation: Identifiable {
let id = UUID()
let name:String
let latitude:Double
let longitude:Double
let pinColor:String = “green”
var coordinate:CLLocationCoordinate2D {
CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
}
}

let MapLocations = [
MapLocation(name: “Albany”, latitude: 31.576950, longitude: -84.178880),
MapLocation(name: “Athens”, latitude: 33.970940, longitude: -83.365050)
]

struct Offices: Identifiable {
let id = UUID()
let name:String
let latitude:Double
let longitude:Double
var pinColor:String = “blue”
var coordinate:CLLocationCoordinate2D {
CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
}
}

extension Offices {
// Put in extension so don’t lose default memberwise initializer
init(name: String, latitude: Double, longitude: Double, pinColor: String ) {
self.name = name
self.latitude = latitude
self.longitude = longitude
self.pinColor = pinColor
}
}
///

Because you made a custom init and changed pinColor to a var. Do one or the other, not both.