Last active
January 13, 2020 21:18
-
-
Save johnnewman/d69b5c28c9f8d0895f9bb5e36eb1baeb to your computer and use it in GitHub Desktop.
Code exhibiting a sorting issue with MGLSymbolStyleLayer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// IconSortViewController.swift | |
// IconOrdering | |
// | |
// Created by John Newman on 11/18/19. | |
// Copyright © 2019 Roadtrippers. All rights reserved. | |
// | |
import UIKit | |
import Mapbox | |
class IconSortViewController: UIViewController { | |
private var map: MGLMapView? | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
let map = MGLMapView(frame: view.bounds) | |
map.delegate = self | |
map.debugMask = MGLMapDebugMaskOptions(rawValue: MGLMapDebugMaskOptions.collisionBoxesMask.rawValue) | |
map.setCenter(CLLocationCoordinate2D(latitude: 38.1399, longitude: -112.1284), zoomLevel: 13, animated: false) | |
view.addSubview(map) | |
self.map = map | |
} | |
private func testShape() -> MGLShapeCollectionFeature { | |
// Trying to draw the red icon on top. | |
let redSort = 0.99999898 | |
let blueSort = 0.99999896 | |
if redSort > blueSort { | |
print("red sort > blue sort") | |
} | |
let featureDict: [String: Any] = ["type": "FeatureCollection", | |
"features": [["type":"Feature", | |
"geometry": ["type":"Point", | |
"coordinates":[-112.1284,38.1399]], | |
"properties":["text":"Red", | |
"icon":"red_circle", | |
"sort":redSort]], | |
["type":"Feature", | |
"geometry": ["type":"Point", | |
"coordinates":[-112.1274,38.1399]], | |
"properties":["text":"Blue", | |
"icon":"blue_circle", | |
"sort":blueSort]]]] | |
let data = try! JSONSerialization.data(withJSONObject: featureDict, options: []) | |
let shape = try! MGLShape(data: data, encoding: String.Encoding.utf8.rawValue) as! MGLShapeCollectionFeature | |
return shape | |
} | |
private func drawShapes() { | |
let source = MGLShapeSource(identifier: "my-source", shape: testShape(), options: nil) | |
let layer = MGLSymbolStyleLayer(identifier: "my-layer", source: source) | |
layer.iconAllowsOverlap = NSExpression(forConstantValue: false) // Flipping to true fixes the issue. | |
layer.textAllowsOverlap = NSExpression(forConstantValue: false) | |
layer.textOptional = NSExpression(forConstantValue: true) | |
layer.text = NSExpression(forKeyPath: "text") | |
layer.iconImageName = NSExpression(forKeyPath: "icon") | |
layer.textOffset = NSExpression(forConstantValue: NSValue(cgVector: CGVector.init(dx: 2, dy: 0))) | |
layer.symbolSortKey = symbolSortKeyExpression() | |
map!.style!.addSource(source) | |
map!.style!.addLayer(layer) | |
} | |
// When using floats, reversing the order doesn't change the outcome. | |
private func symbolSortKeyExpression() -> NSExpression { | |
return NSExpression(forKeyPath: "sort") | |
// return NSExpression(forFunction: "multiply:by:", arguments: [NSExpression(forKeyPath: "sort"), NSExpression(forConstantValue: -1)]) | |
} | |
} | |
extension IconSortViewController : MGLMapViewDelegate { | |
func mapView(_ mapView: MGLMapView, didFinishLoading style: MGLStyle) { | |
let iconRect = CGRect(x: 0, y: 0, width: 30, height: 30) | |
let renderer = UIGraphicsImageRenderer(size: iconRect.size) | |
let red = renderer.image { (context) in | |
UIColor.white.setFill() | |
context.cgContext.fillEllipse(in: iconRect) | |
UIColor.red.setFill() | |
context.cgContext.fillEllipse(in: iconRect.insetBy(dx: 2, dy: 2)) | |
} | |
let blue = renderer.image { (context) in | |
UIColor.white.setFill() | |
context.cgContext.fillEllipse(in: iconRect) | |
UIColor.blue.setFill() | |
context.cgContext.fillEllipse(in: iconRect.insetBy(dx: 2, dy: 2)) | |
} | |
style.setImage(red, forName: "red_circle") | |
style.setImage(blue, forName: "blue_circle") | |
drawShapes() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment