Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Livemap geocoding #63

Merged
merged 13 commits into from
Dec 5, 2019
Prev Previous commit
Next Next commit
Added ApplyCentroidsSystem.
Added dynamic entity for text.
  • Loading branch information
ISeleznev-HORIS committed Nov 28, 2019
commit 0669089213c503469ba8bcae5b74a379b622b1b0
3 changes: 3 additions & 0 deletions livemap/src/commonMain/kotlin/jetbrains/livemap/LiveMap.kt
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import jetbrains.livemap.core.rendering.layers.LayersRenderingSystem
import jetbrains.livemap.core.rendering.layers.RenderTarget
import jetbrains.livemap.core.rendering.primitives.Rectangle
import jetbrains.livemap.effects.GrowingPath
import jetbrains.livemap.entities.geocoding.ApplyCentroidsSystem
import jetbrains.livemap.entities.geocoding.BBoxGeocodingSystem
import jetbrains.livemap.entities.geocoding.PointGeocodingSystem
import jetbrains.livemap.entities.geocoding.RegionIdGeocodingSystem
Expand Down Expand Up @@ -177,6 +178,8 @@ class LiveMap(
PointGeocodingSystem(componentManager, myGeocodingService),
BBoxGeocodingSystem(componentManager, myGeocodingService, bboxEmptinessChecker),

ApplyCentroidsSystem(componentManager),

ScaleUpdateSystem(componentManager),

// Service systems
Expand Down
46 changes: 26 additions & 20 deletions livemap/src/commonMain/kotlin/jetbrains/livemap/api/Texts.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@
package jetbrains.livemap.api

import jetbrains.datalore.base.projectionGeometry.Vec
import jetbrains.datalore.base.projectionGeometry.times
import jetbrains.datalore.base.spatial.LonLat
import jetbrains.datalore.base.values.Color
import jetbrains.livemap.core.ecs.EcsEntity
import jetbrains.livemap.core.ecs.addComponents
import jetbrains.livemap.core.rendering.layers.LayerGroup
import jetbrains.livemap.entities.Entities.MapEntityFactory
import jetbrains.livemap.entities.placement.ScreenDimensionComponent
import jetbrains.livemap.entities.placement.ScreenOffsetComponent
import jetbrains.livemap.entities.geocoding.PointTag
import jetbrains.livemap.entities.rendering.*
import jetbrains.livemap.entities.rendering.Renderers.TextRenderer
import jetbrains.livemap.projections.MapProjection
Expand Down Expand Up @@ -53,10 +51,8 @@ class TextBuilder(
private val myMapProjection: MapProjection
) {
var index: Int = 0
var mapId: String = ""
var regionId: String = ""

lateinit var point: Vec<LonLat>
var mapId: String? = null
var point: Vec<LonLat>? = null

var fillColor: Color = Color.BLACK
var strokeColor: Color = Color.TRANSPARENT
Expand All @@ -75,21 +71,31 @@ class TextBuilder(
): EcsEntity {
val textSpec = createTextSpec(textMeasurer)

return when {
point != null -> createStaticEntity(textSpec)
mapId != null -> createDynamicEntity()
else -> error("Can't create line entity. [point] and [mapId] is null.")
}.addComponents {
+ TextComponent().apply { this.textSpec = textSpec }
+ StyleComponent().apply {
setFillColor([email protected])
setStrokeColor([email protected])
setStrokeWidth([email protected])
}
}
}

private fun createStaticEntity(textSpec: TextSpec): EcsEntity {
return myFactory
.createMapEntity(myMapProjection.project(point!!), TextRenderer(), "map_ent_s_text")
.addScreenOffsetAndDimension(textSpec)
}

private fun createDynamicEntity(): EcsEntity {
return myFactory
.createMapEntity(myMapProjection.project(point), TextRenderer(), "map_ent_text")
.createDynamicMapEntity(mapId!!, TextRenderer(),"map_ent_d_text_$mapId")
.addComponents {
+ ScreenOffsetComponent().apply {
offset = textSpec.dimension * -0.5
}
+ ScreenDimensionComponent().apply {
dimension = textSpec.dimension
}
+ TextComponent().apply { this.textSpec = textSpec }
+ StyleComponent().apply {
setFillColor([email protected])
setStrokeColor([email protected])
setStrokeWidth([email protected])
}
+ PointTag()
}
}

Expand Down
16 changes: 16 additions & 0 deletions livemap/src/commonMain/kotlin/jetbrains/livemap/api/Utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
package jetbrains.livemap.api

import jetbrains.datalore.base.projectionGeometry.*
import jetbrains.livemap.core.ecs.EcsEntity
import jetbrains.livemap.core.ecs.addComponents
import jetbrains.livemap.entities.placement.ScreenDimensionComponent
import jetbrains.livemap.entities.placement.ScreenOffsetComponent
import jetbrains.livemap.entities.rendering.TextSpec
import jetbrains.livemap.projections.World
import jetbrains.livemap.projections.WorldPoint
import jetbrains.livemap.projections.WorldRectangle
Expand Down Expand Up @@ -81,4 +86,15 @@ fun createLineBBox(
explicitVec(strokeWidth, mapRect.height)
)
}
}

fun EcsEntity.addScreenOffsetAndDimension(textSpec: TextSpec): EcsEntity {
return addComponents {
+ ScreenOffsetComponent().apply {
offset = textSpec.dimension * -0.5
}
+ ScreenDimensionComponent().apply {
dimension = textSpec.dimension
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* Copyright (c) 2019. JetBrains s.r.o.
* Use of this source code is governed by the MIT license that can be found in the LICENSE file.
*/

package jetbrains.livemap.entities.geocoding

import jetbrains.livemap.LiveMapContext
import jetbrains.livemap.api.addScreenOffsetAndDimension
import jetbrains.livemap.api.createLineBBox
import jetbrains.livemap.api.createLineGeometry
import jetbrains.livemap.core.ecs.AbstractSystem
import jetbrains.livemap.core.ecs.EcsComponentManager
import jetbrains.livemap.core.ecs.EcsEntity
import jetbrains.livemap.core.ecs.addComponents
import jetbrains.livemap.entities.geometry.WorldGeometryComponent
import jetbrains.livemap.entities.placement.ScreenLoopComponent
import jetbrains.livemap.entities.placement.ScreenOriginComponent
import jetbrains.livemap.entities.placement.WorldDimensionComponent
import jetbrains.livemap.entities.placement.WorldOriginComponent
import jetbrains.livemap.entities.rendering.StyleComponent
import jetbrains.livemap.entities.rendering.TextComponent
import jetbrains.livemap.projections.MapProjection
import jetbrains.livemap.projections.WorldPoint

class ApplyCentroidsSystem(
componentManager: EcsComponentManager
) : AbstractSystem<LiveMapContext>(componentManager) {

private lateinit var myMapProjection: MapProjection

override fun initImpl(context: LiveMapContext) {
myMapProjection = context.mapProjection
}

override fun updateImpl(context: LiveMapContext, dt: Double) {
getEntities(CentroidComponent::class)
.toList()
.forEach { entity ->
val point = entity.get<CentroidComponent>().point

if (entity.contains(HorizontalComponent::class)) {
applyToLine(entity, point)
} else if(entity.contains(TextComponent::class)) {
applyToText(entity, point)
} else {
applyToPoint(entity, point)
}

entity.removeComponent(CentroidComponent::class)
}
}

private fun applyToText(entity: EcsEntity, point: WorldPoint) {

entity.addComponents {
+ WorldOriginComponent(point)
+ ScreenLoopComponent()
+ ScreenOriginComponent()
}.addScreenOffsetAndDimension(entity.get<TextComponent>().textSpec)
}

private fun applyToPoint(entity: EcsEntity, point: WorldPoint) {
entity.addComponents {
+ WorldOriginComponent(point)
+ ScreenLoopComponent()
+ ScreenOriginComponent()
}
}

private fun applyToLine(entity: EcsEntity, point: WorldPoint) {
val horizontal = entity.get<HorizontalComponent>().horizontal
val strokeWidth = entity.get<StyleComponent>().strokeWidth
val line = createLineGeometry(point, horizontal, myMapProjection.mapRect)
val bbox = createLineBBox(point, strokeWidth, horizontal, myMapProjection.mapRect)

entity.addComponents {
+ WorldOriginComponent(bbox.origin)
+ WorldDimensionComponent(bbox.dimension)
+ WorldGeometryComponent().apply { geometry = line }
+ ScreenLoopComponent()
+ ScreenOriginComponent()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
package jetbrains.livemap.entities.geocoding

import jetbrains.livemap.core.ecs.EcsComponent
import jetbrains.livemap.projections.WorldPoint

class PointTag : EcsComponent
class HorizontalComponent(val horizontal: Boolean) : EcsComponent

class HorizontalComponent(val horizontal: Boolean) : EcsComponent

class CentroidComponent(val point: WorldPoint): EcsComponent
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,15 @@
package jetbrains.livemap.entities.geocoding

import jetbrains.datalore.base.projectionGeometry.reinterpret
import jetbrains.gis.geoprotocol.GeoRequest.FeatureOption.*
import jetbrains.gis.geoprotocol.GeoRequest.FeatureOption.CENTROID
import jetbrains.gis.geoprotocol.GeoRequestBuilder.ExplicitRequestBuilder
import jetbrains.gis.geoprotocol.GeoResponse.SuccessGeoResponse.GeocodedFeature
import jetbrains.gis.geoprotocol.GeocodingService
import jetbrains.livemap.LiveMapContext
import jetbrains.livemap.LiveMapSystem
import jetbrains.livemap.api.createLineBBox
import jetbrains.livemap.api.createLineGeometry
import jetbrains.livemap.core.ecs.EcsComponentManager
import jetbrains.livemap.core.ecs.addComponents
import jetbrains.livemap.entities.geometry.WorldGeometryComponent
import jetbrains.livemap.entities.placement.ScreenLoopComponent
import jetbrains.livemap.entities.placement.ScreenOriginComponent
import jetbrains.livemap.entities.placement.WorldDimensionComponent
import jetbrains.livemap.entities.placement.WorldOriginComponent
import jetbrains.livemap.entities.regions.RegionIdComponent
import jetbrains.livemap.entities.rendering.StyleComponent
import jetbrains.livemap.projections.MapProjection

class PointGeocodingSystem(
Expand Down Expand Up @@ -60,30 +52,7 @@ class PointGeocodingSystem(
entity.get<RegionIdComponent>().regionId?.let { regionId ->
centroidsById[regionId]?.let { coord ->
entity.removeComponent(RegionIdComponent::class)

val worldPoint = myMapProjection.project(coord.reinterpret())

if (entity.contains(HorizontalComponent::class)) {
val horizontal = entity.get<HorizontalComponent>().horizontal
val strokeWidth = entity.get<StyleComponent>().strokeWidth
val line = createLineGeometry(worldPoint, horizontal, myMapProjection.mapRect)
val bbox = createLineBBox(worldPoint, strokeWidth, horizontal, myMapProjection.mapRect)

entity.addComponents {
+ WorldOriginComponent(bbox.origin)
+ WorldDimensionComponent(bbox.dimension)
+ WorldGeometryComponent().apply { geometry = line }
}
} else {
entity.addComponents {
+ WorldOriginComponent(worldPoint)
}
}

entity.addComponents {
+ ScreenLoopComponent()
+ ScreenOriginComponent()
}
entity.addComponents { + CentroidComponent(myMapProjection.project(coord.reinterpret())) }
}
}
}
Expand Down