Skip to content

Commit

Permalink
Add deducted place algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
dacr committed Sep 1, 2024
1 parent 701de91 commit dd81262
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package fr.janalyse.sotohp.cli
import fr.janalyse.sotohp.core.*
import fr.janalyse.sotohp.model.*
import fr.janalyse.sotohp.processor.NormalizeProcessor
import fr.janalyse.sotohp.store.{LazyPhoto, PhotoStoreIssue, PhotoStoreService}
import fr.janalyse.sotohp.store.{LazyPhoto, PhotoStoreIssue, PhotoStoreService, PhotoStoreSystemIssue}
import zio.*
import zio.config.typesafe.*
import zio.lmdb.LMDB
Expand All @@ -20,7 +20,10 @@ case class QuickFixPhoto(
state: PhotoState,
event: Option[PhotoEvent] = None,
place: Option[PhotoPlace] = None
)
) {
def epoch = state.photoTimestamp.toEpochSecond
def id = state.photoId
}

object PlacesFix extends ZIOAppDefault with CommonsCLI {

Expand Down Expand Up @@ -55,19 +58,19 @@ object PlacesFix extends ZIOAppDefault with CommonsCLI {
index <- photos.indices
current = photos(index)
if current.place.isEmpty
if !state.fixed.contains(current.state.photoId)
if !state.fixed.contains(current.id)
foundNearestBeforeWithGPS = photos.take(index).findLast(_.place.exists(!_.deducted))
foundNearestAfterWithGPS = photos.drop(index).find(_.place.exists(!_.deducted))
if foundNearestBeforeWithGPS.isDefined && foundNearestAfterWithGPS.isDefined
nearestPlaceBefore = foundNearestBeforeWithGPS.get.place.get
nearestPlaceAfter = foundNearestAfterWithGPS.get.place.get
distance = nearestPlaceBefore.distanceTo(nearestPlaceAfter)
nearestTimestampBefore = foundNearestBeforeWithGPS.get.state.photoTimestamp.toEpochSecond
nearestTimestampAfter = foundNearestAfterWithGPS.get.state.photoTimestamp.toEpochSecond
nearestTimestampBefore = foundNearestBeforeWithGPS.get.epoch
nearestTimestampAfter = foundNearestAfterWithGPS.get.epoch
elapsed = nearestTimestampAfter - nearestTimestampBefore
if distance < 500 // 600 meters
if elapsed < 5 * 3600
toFixPhotoId = current.state.photoId
if distance < 500 // 500 meters
if elapsed < 5 * 3600 // 5 hours
toFixPhotoId = current.id
deductedPlace = nearestPlaceBefore.copy(deducted = true)
} yield toFixPhotoId -> deductedPlace

Expand All @@ -76,25 +79,52 @@ object PlacesFix extends ZIOAppDefault with CommonsCLI {
} yield state.copy(state.fixed ++ newFixed)
}

def quickFixByFirstTakenPhotosWithoutPlace(state: QuickFixState, photos: Chunk[QuickFixPhoto]): ZIO[PhotoStoreService, PhotoStoreIssue, QuickFixState] = {
val fixable = photos.toList match {
case Nil => Nil
case ref :: Nil => Nil
case ref :: _ :: Nil => Nil
case ref :: others if (others.head.epoch - ref.epoch) > 6 * 3600 =>
others.takeWhile(o => o.place.isEmpty) match {
case Nil => Nil
case toFix =>
others.find(_.place.isDefined).filter(p => (p.epoch - toFix.head.epoch) < 30 * 60).flatMap(_.place) match {
case None => Nil
case Some(found) => toFix.map(p => p.id -> found)
}
}

case _ => Nil
}

for {
newFixed <- ZIO.foreach(fixable)(fixPlaceInStorage)
// newFixed <- ZIO.foreach(fixable)(p => Console.printLine(p).as(p._1)).mapError(err => PhotoStoreSystemIssue(err.getMessage))
} yield state.copy(state.fixed ++ newFixed)
}

val logic = ZIO.logSpan("PlacesFix") {
val photoStream = PhotoStream.photoLazyStream()
val initialState = QuickFixState()
val photoStream = PhotoStream.photoLazyStream()
for {
_ <- ZIO.logInfo("step 1 - quickFixByTimeWindow")
step1State <- photoStream
.mapZIO(convert)
.sliding(300, 50)
.runFoldZIO(initialState)((state, photos) => quickFixByTimeWindow(state, photos))
// events <- photoStream
// .mapZIO(convert)
.sliding(200, 50)
.runFoldZIO(QuickFixState())((state, photos) => quickFixByTimeWindow(state, photos))
_ <- ZIO.logInfo("step 2 - quickFixByFirstTakenPhotosWithoutPlace")
step2state <- photoStream
.mapZIO(convert)
.sliding(100, 1)
.runFoldZIO(QuickFixState())((state, photos) => quickFixByFirstTakenPhotosWithoutPlace(state, photos))
// .filter(_.event.isDefined)
// .map(_.event.get)
// .runFold(Set.empty[PhotoEvent])((set, event) => set + event)
// step2State <- photoStream
// .mapZIO(convert)
// .filter(_.event.isDefined)
// .runFoldZIO(step1State)((state, photos) => ???)
finalState = step1State
_ <- ZIO.logInfo(s"${finalState.fixed.size} places fixed using timeWindow")
fixed = step1State.fixed ++ step2state.fixed
_ <- ZIO.logInfo(s"${fixed.size} places fixed using timeWindow")
} yield ()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ object SynchronizeAndProcess extends ZIOAppDefault with CommonsCLI {
.mapZIO(facesProcessor.analyze)
.mapZIO(p => facesFeaturesProcessor.extractPhotoFaceFeatures(p).as(p))
.filter(_.lastSynchronized.isEmpty) // TODO it only synchronizes new photos, changes are not synchronized
.grouped(500)
.grouped(20)
.mapZIO(SearchService.publish)
.mapZIO(updatePhotoStates)
.map(_.size)
Expand Down

0 comments on commit dd81262

Please sign in to comment.