All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.geomesa.gs.styling.GeoMesaMarkFactory.scala Maven / Gradle / Ivy

/***********************************************************************
 * Copyright (c) 2013-2017 Commonwealth Computer Research, Inc.
 * All rights reserved. This program and the accompanying materials are
 * made available under the terms of the GNU GENERAL PUBLIC LICENSE,
 * Version 2 which accompanies this distribution and is available at
 * https://opensource.org/licenses/GPL-2.0.
 ***********************************************************************/

package org.geomesa.gs.styling

import java.awt.{Graphics2D, Shape}
import java.lang.{Float => jFloat, String => jString}

import com.github.benmanes.caffeine.cache.{CacheLoader, Caffeine}
import com.typesafe.scalalogging.LazyLogging
import org.geotools.filter.LiteralExpressionImpl
import org.geotools.geometry.jts.TransformedShape
import org.geotools.renderer.style._
import org.opengis.feature.Feature
import org.opengis.filter.expression.Expression

class GeoMesaMarkFactory extends TTFMarkFactory {
  // To use this factory utilize the 'geomesaFastMark' ogc function

   val cache = Caffeine.newBuilder().build[String, Array[Shape]](
      new CacheLoader[String, Array[Shape]] {
        override def load(key: String): Array[Shape] = {
          val notRotated = GeoMesaMarkFactory.lookupShape(key)
          if (notRotated != null) {
            Array.tabulate[Shape](360) { i =>
              val ts = new TransformedShape()
              ts.shape = notRotated
              ts.rotate(-i * Math.PI / 180)
              ts
            }
          } else {
            Array.tabulate[Shape](360) { null }
          }
        }
      }
   )

  override def getShape(graphics: Graphics2D, symbolUrl: Expression, feature: Feature): Shape = {
    symbolUrl.evaluate(feature, classOf[(jString, jFloat)]) match {
      case (icon: jString, rotation: jFloat) =>
        val normRotation: Int = {
          if (rotation < 0) {
            (rotation + 360).toInt
          } else {
            rotation.toInt
          }
        }
        require(normRotation >= 0 && normRotation <= 360)
        cache.get(icon)(normRotation)
      case _ => null
    }
  }
}

object GeoMesaMarkFactory extends LazyLogging {
  val ttfFactory = new TTFMarkFactory

  def lookupShape(url: String): Shape = {
    if (url.startsWith("ttf://")) {
      logger.debug(s"Looking up shape for url $url")
      val exp = new LiteralExpressionImpl(url)
      val shape = ttfFactory.getShape(null, exp, null)
      shape
    } else {
      null
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy