@@ -157,8 +157,6 @@ object MapStyles {
157157 val QUIET_DARK = Quiet (" #172234" , " #0B1625" , " #172A24" , " #233049" , " #1E2A40" , " #2E3C57" , " #1C283B" , " #6C7B94" , " #46709A" )
158158
159159 /* * A quiet map for the train diagram: land, water, parks, faint roads and suburb names, so the lines stand out. */
160- fun diagramJson (dark : Boolean ): String = diagram(dark)
161-
162160 private fun diagram (dark : Boolean ): String {
163161 val c = if (dark) QUIET_DARK else QUIET_LIGHT
164162 fun arr (vararg v : Any ) = JSONArray ().also { a -> v.forEach { a.put(it) } }
@@ -525,76 +523,61 @@ private fun byZoom(p: String) = Expression.interpolate(Expression.linear(), Expr
525523 */
526524private fun drawLayers (s : Style , lines : List <MapLine >, links : List <MapLine >, stops : List <MapStop >, basemap : Basemap , dark : Boolean ) {
527525 fun put (layer : Layer ) = if (s.getLayer(" crowd-dots" ) != null ) s.addLayerBelow(layer, " crowd-dots" ) else s.addLayer(layer)
526+ val zoom = Expression .zoom()
528527 if (s.getSource(" akl-lines" ) == null ) {
528+ val dg = basemap == Basemap .Diagram
529+ val caseCol = when {
530+ dg -> if (dark) MapStyles .QUIET_DARK .bg else MapStyles .QUIET_LIGHT .bg
531+ basemap == Basemap .Streets && ! dark -> " #FFFFFF"
532+ else -> " #0B1628"
533+ }
529534 for (id in listOf (" akl-lines" , " akl-links" , " akl-stops" )) s.addSource(GeoJsonSource (id))
530- aklLayers(basemap, dark).forEach { put(it) }
535+ val round = arrayOf(PropertyFactory .lineCap(Property .LINE_CAP_ROUND ), PropertyFactory .lineJoin(Property .LINE_JOIN_ROUND ))
536+ put(LineLayer (" akl-lines-case" , " akl-lines" ).withProperties(* round,
537+ PropertyFactory .lineColor(Expression .switchCase(Expression .toBool(Expression .get(" z" )), Expression .color(android.graphics.Color .parseColor(caseCol)),
538+ Expression .color(android.graphics.Color .parseColor(" #0B1628" )))),
539+ PropertyFactory .lineOpacity(Expression .switchCase(Expression .toBool(Expression .get(" z" )), Expression .literal(if (dg) 1f else 0.8f ), Expression .literal(0.55f ))),
540+ PropertyFactory .lineWidth(byZoom(" cw" )),
541+ PropertyFactory .lineOffset(byZoom(" o" ))))
542+ put(LineLayer (" akl-lines" , " akl-lines" ).withProperties(* round,
543+ PropertyFactory .lineColor(Expression .toColor(Expression .get(" c" ))),
544+ PropertyFactory .lineWidth(byZoom(" w" )),
545+ PropertyFactory .lineOffset(byZoom(" o" ))))
546+ put(LineLayer (" akl-links-case" , " akl-links" ).withProperties(* round,
547+ PropertyFactory .lineColor(Expression .toColor(Expression .get(" c" ))),
548+ PropertyFactory .lineWidth(Expression .interpolate(Expression .linear(), zoom,
549+ Expression .stop(9 , 6f ), Expression .stop(12 , 11.4f ), Expression .stop(16 , 19f )))))
550+ put(LineLayer (" akl-links" , " akl-links" ).withProperties(* round,
551+ PropertyFactory .lineColor(Color .White .toArgb()),
552+ PropertyFactory .lineWidth(Expression .interpolate(Expression .linear(), zoom,
553+ Expression .stop(9 , 2.8f ), Expression .stop(12 , 6.2f ), Expression .stop(16 , 13.8f )))))
554+ put(CircleLayer (" akl-stops" , " akl-stops" ).withProperties(
555+ PropertyFactory .circleColor(Color .White .toArgb()),
556+ PropertyFactory .circleStrokeColor(Expression .toColor(Expression .get(" c" ))),
557+ PropertyFactory .circleRadius(byZoom(" rad" )),
558+ PropertyFactory .circleStrokeWidth(Expression .interpolate(Expression .linear(), zoom,
559+ Expression .stop(9 , num(" sw9" )), Expression .stop(13 , num(" sw13" ))))))
560+ // names: the most important stations win the space, the rest appear as you zoom in
561+ val darkLabels = basemap != Basemap .Satellite && dark
562+ put(SymbolLayer (" akl-stop-labels" , " akl-stops" ).withProperties(
563+ PropertyFactory .textField(Expression .step(zoom, Expression .toString(Expression .get(" l0" )),
564+ Expression .stop(10.4 , Expression .toString(Expression .get(" l1" ))), Expression .stop(11 , Expression .toString(Expression .get(" label" ))))),
565+ PropertyFactory .textFont(arrayOf(" Noto Sans Bold" )),
566+ PropertyFactory .textSize(Expression .interpolate(Expression .linear(), zoom,
567+ Expression .stop(10 , num(" ts10" )), Expression .stop(14 , num(" ts14" )))),
568+ PropertyFactory .textVariableAnchor(arrayOf(Property .TEXT_ANCHOR_LEFT , Property .TEXT_ANCHOR_RIGHT , Property .TEXT_ANCHOR_TOP ,
569+ Property .TEXT_ANCHOR_BOTTOM , Property .TEXT_ANCHOR_TOP_LEFT , Property .TEXT_ANCHOR_BOTTOM_RIGHT )),
570+ PropertyFactory .textRadialOffset(0.95f ),
571+ PropertyFactory .textJustify(Property .TEXT_JUSTIFY_AUTO ),
572+ PropertyFactory .symbolSortKey(num(" rank" )),
573+ PropertyFactory .textPadding(3f ),
574+ PropertyFactory .textMaxWidth(9f ),
575+ PropertyFactory .textColor(android.graphics.Color .parseColor(if (darkLabels) " #E6ECF5" else " #1A2744" )),
576+ PropertyFactory .textHaloColor(if (darkLabels) android.graphics.Color .parseColor(if (dg) MapStyles .QUIET_DARK .bg else " #0B1628" )
577+ else android.graphics.Color .argb(235 , 255 , 255 , 255 )),
578+ PropertyFactory .textHaloWidth(2.2f )))
531579 }
532- val (l, k, st) = aklData(lines, links, stops)
533- s.getSourceAs<GeoJsonSource >(" akl-lines" )?.setGeoJson(l)
534- s.getSourceAs<GeoJsonSource >(" akl-links" )?.setGeoJson(k)
535- s.getSourceAs<GeoJsonSource >(" akl-stops" )?.setGeoJson(st)
536- }
537-
538- /* * The route lines, platform bars, stop dots and names as map layers, bottom to top, fed by akl-lines, akl-links and akl-stops. */
539- internal fun aklLayers (basemap : Basemap , dark : Boolean ): List <Layer > {
540- val out = ArrayList <Layer >()
541- val zoom = Expression .zoom()
542- val dg = basemap == Basemap .Diagram
543- val caseCol = when {
544- dg -> if (dark) MapStyles .QUIET_DARK .bg else MapStyles .QUIET_LIGHT .bg
545- basemap == Basemap .Streets && ! dark -> " #FFFFFF"
546- else -> " #0B1628"
547- }
548- val round = arrayOf(PropertyFactory .lineCap(Property .LINE_CAP_ROUND ), PropertyFactory .lineJoin(Property .LINE_JOIN_ROUND ))
549- out + = LineLayer (" akl-lines-case" , " akl-lines" ).withProperties(* round,
550- PropertyFactory .lineColor(Expression .switchCase(Expression .toBool(Expression .get(" z" )), Expression .color(android.graphics.Color .parseColor(caseCol)),
551- Expression .color(android.graphics.Color .parseColor(" #0B1628" )))),
552- PropertyFactory .lineOpacity(Expression .switchCase(Expression .toBool(Expression .get(" z" )), Expression .literal(if (dg) 1f else 0.8f ), Expression .literal(0.55f ))),
553- PropertyFactory .lineWidth(byZoom(" cw" )),
554- PropertyFactory .lineOffset(byZoom(" o" )))
555- out + = LineLayer (" akl-lines" , " akl-lines" ).withProperties(* round,
556- PropertyFactory .lineColor(Expression .toColor(Expression .get(" c" ))),
557- PropertyFactory .lineWidth(byZoom(" w" )),
558- PropertyFactory .lineOffset(byZoom(" o" )))
559- out + = LineLayer (" akl-links-case" , " akl-links" ).withProperties(* round,
560- PropertyFactory .lineColor(Expression .toColor(Expression .get(" c" ))),
561- PropertyFactory .lineWidth(Expression .interpolate(Expression .linear(), zoom,
562- Expression .stop(9 , 6f ), Expression .stop(12 , 11.4f ), Expression .stop(16 , 19f ))))
563- out + = LineLayer (" akl-links" , " akl-links" ).withProperties(* round,
564- PropertyFactory .lineColor(Color .White .toArgb()),
565- PropertyFactory .lineWidth(Expression .interpolate(Expression .linear(), zoom,
566- Expression .stop(9 , 2.8f ), Expression .stop(12 , 6.2f ), Expression .stop(16 , 13.8f ))))
567- out + = CircleLayer (" akl-stops" , " akl-stops" ).withProperties(
568- PropertyFactory .circleColor(Color .White .toArgb()),
569- PropertyFactory .circleStrokeColor(Expression .toColor(Expression .get(" c" ))),
570- PropertyFactory .circleRadius(byZoom(" rad" )),
571- PropertyFactory .circleStrokeWidth(Expression .interpolate(Expression .linear(), zoom,
572- Expression .stop(9 , num(" sw9" )), Expression .stop(13 , num(" sw13" )))))
573- // names: the most important stations win the space, the rest appear as you zoom in
574- val darkLabels = basemap != Basemap .Satellite && dark
575- out + = SymbolLayer (" akl-stop-labels" , " akl-stops" ).withProperties(
576- PropertyFactory .textField(Expression .step(zoom, Expression .toString(Expression .get(" l0" )),
577- Expression .stop(10.4 , Expression .toString(Expression .get(" l1" ))), Expression .stop(11 , Expression .toString(Expression .get(" label" ))))),
578- PropertyFactory .textFont(arrayOf(" Noto Sans Bold" )),
579- PropertyFactory .textSize(Expression .interpolate(Expression .linear(), zoom,
580- Expression .stop(10 , num(" ts10" )), Expression .stop(14 , num(" ts14" )))),
581- PropertyFactory .textVariableAnchor(arrayOf(Property .TEXT_ANCHOR_LEFT , Property .TEXT_ANCHOR_RIGHT , Property .TEXT_ANCHOR_TOP ,
582- Property .TEXT_ANCHOR_BOTTOM , Property .TEXT_ANCHOR_TOP_LEFT , Property .TEXT_ANCHOR_BOTTOM_RIGHT )),
583- PropertyFactory .textRadialOffset(0.95f ),
584- PropertyFactory .textJustify(Property .TEXT_JUSTIFY_AUTO ),
585- PropertyFactory .symbolSortKey(num(" rank" )),
586- PropertyFactory .textPadding(3f ),
587- PropertyFactory .textMaxWidth(9f ),
588- PropertyFactory .textColor(android.graphics.Color .parseColor(if (darkLabels) " #E6ECF5" else " #1A2744" )),
589- PropertyFactory .textHaloColor(if (darkLabels) android.graphics.Color .parseColor(if (dg) MapStyles .QUIET_DARK .bg else " #0B1628" )
590- else android.graphics.Color .argb(235 , 255 , 255 , 255 )),
591- PropertyFactory .textHaloWidth(2.2f ))
592- return out
593- }
594-
595- /* * The features for akl-lines, akl-links and akl-stops. */
596- internal fun aklData (lines : List <MapLine >, links : List <MapLine >, stops : List <MapStop >): Triple <FeatureCollection , FeatureCollection , FeatureCollection > {
597- val lineFc = FeatureCollection .fromFeatures(lines.map { l ->
580+ s.getSourceAs<GeoJsonSource >(" akl-lines" )?.setGeoJson(FeatureCollection .fromFeatures(lines.map { l ->
598581 Feature .fromGeometry(MultiLineString .fromLngLats(l.parts.map { part -> part.map { Point .fromLngLat(it.second, it.first) } })).also { f ->
599582 val k9 = if (l.z) 0.6f else 1f
600583 val k16 = if (l.z) 1.9f else 1f
@@ -607,12 +590,12 @@ internal fun aklData(lines: List<MapLine>, links: List<MapLine>, stops: List<Map
607590 f.addNumberProperty(" o$k " , l.offset * v)
608591 }
609592 }
610- })
611- val linkFc = FeatureCollection .fromFeatures(links.map { l ->
593+ }))
594+ s.getSourceAs< GeoJsonSource >( " akl-links " )?.setGeoJson( FeatureCollection .fromFeatures(links.map { l ->
612595 Feature .fromGeometry(MultiLineString .fromLngLats(l.parts.map { part -> part.map { Point .fromLngLat(it.second, it.first) } }))
613596 .also { it.addStringProperty(" c" , hex(l.color)) }
614- })
615- val stopFc = FeatureCollection .fromFeatures(stops.map { st ->
597+ }))
598+ s.getSourceAs< GeoJsonSource >( " akl-stops " )?.setGeoJson( FeatureCollection .fromFeatures(stops.map { st ->
616599 Feature .fromGeometry(Point .fromLngLat(st.lon, st.lat)).also { f ->
617600 val label = st.label ? : " "
618601 f.addStringProperty(" c" , hex(st.color))
@@ -628,8 +611,7 @@ internal fun aklData(lines: List<MapLine>, links: List<MapLine>, stops: List<Map
628611 f.addNumberProperty(" ts10" , if (st.rank <= 0 ) 12f else 11f )
629612 f.addNumberProperty(" ts14" , if (st.rank <= 0 ) 14f else 12.5f )
630613 }
631- })
632- return Triple (lineFc, linkFc, stopFc)
614+ }))
633615}
634616
635617/* * The crowd's source and layers: a dot per vehicle, a heading arrow, and the route once zoomed in. */
0 commit comments