@@ -8,7 +8,6 @@ import page.ooooo.geoshare.R
88import page.ooooo.geoshare.lib.ILog
99import page.ooooo.geoshare.lib.Uri
1010import page.ooooo.geoshare.lib.extensions.doubleGroupOrNull
11- import page.ooooo.geoshare.lib.extensions.forEachReversed
1211import page.ooooo.geoshare.lib.extensions.groupOrNull
1312import page.ooooo.geoshare.lib.extensions.matchEntire
1413import page.ooooo.geoshare.lib.extensions.toLatLonPoint
@@ -45,18 +44,23 @@ object GoogleMapsInput : Input.HasShortUri, Input.HasHtml, Input.HasWeb {
4544 uri.run {
4645 // Try query parameters for all URLs
4746
48- listOf (" destination" , " q" , " query" , " ll" , " viewpoint" , " center" )
49- .firstNotNullOfOrNull { key -> LAT_LON_PATTERN .matchEntire(queryParams[key]) }
50- ?.toLatLonPoint()
51- ?.also { points.add(it) }
52-
53- listOf (" destination" , " q" , " query" )
54- .firstNotNullOfOrNull { key -> Q_PARAM_PATTERN .matchEntire(queryParams[key]) }
55- ?.groupOrNull()
56- ?.also { defaultName = it }
57-
5847 Z_PATTERN .matchEntire(queryParams[" zoom" ])?.doubleGroupOrNull()?.also { defaultZ = it }
5948
49+ listOf (" origin" , " destination" , " q" , " query" , " ll" , " viewpoint" , " center" ).forEach { key ->
50+ (LAT_LON_PATTERN .matchEntire(queryParams[key])?.toLatLonPoint()
51+ ? : Q_PARAM_PATTERN .matchEntire(queryParams[key])?.groupOrNull()?.let { NaivePoint (name = it) })
52+ ?.let {
53+ points.add(it)
54+ if (key != " origin" ) {
55+ if (! it.hasCoordinates()) {
56+ // Go to HTML parsing if needed
57+ htmlUriString = uri.toString()
58+ }
59+ return @run
60+ }
61+ }
62+ }
63+
6064 // Parse path parts
6165
6266 val partsThatSupportUriParsing = setOf (" dir" , " place" , " search" )
@@ -65,55 +69,59 @@ object GoogleMapsInput : Input.HasShortUri, Input.HasHtml, Input.HasWeb {
6569 val firstPart = parts.firstOrNull()
6670 if (firstPart in partsThatSupportUriParsing || firstPart?.startsWith(' @' ) == true ) {
6771 // Iterate path parts in reverse order
68- var centerCoords: Pair <Double , Double >? = null
6972 val pointPattern = Regex (""" $LAT ,$LON .*""" )
70- parts.dropWhile { it in partsThatSupportUriParsing }.forEachReversed { part ->
73+ parts.dropWhile { it in partsThatSupportUriParsing }.forEach { part ->
7174 if (part.startsWith(" data=" )) {
7275 // Data
7376 // /data=...!3d44.4490541!4d26.0888398...
74- Regex (""" !3d$LAT !4d$LON """ ).find(part)?.toLatLonPoint()?.also { points.add(it) }
77+ Regex (""" !3d$LAT !4d$LON """ ).find(part)?.toLatLonPoint()?.also {
78+ // Overwrite coordinates of previously found points with /data= but copy last point name
79+ points.lastOrNull().let { lastPoint ->
80+ points.clear()
81+ points.add(it.copy(name = lastPoint?.name))
82+ }
83+ } ? :
7584 // /data=...!1d13.4236883!2d52.4858222...!1d13.4255518!2d52.4881038...
76- points.addAll((Regex (""" !1d$LON !2d$LAT """ ).findAll(part)).mapNotNull { it.toLonLatPoint() })
77- } else if (part.startsWith(' @' ) && centerCoords == null ) {
85+ Regex (""" !1d$LON !2d$LAT """ ).findAll(part).mapNotNull { it.toLonLatPoint() }
86+ .toList().takeIf { it.isNotEmpty() }?.let {
87+ if (it.size == points.size) {
88+ // Overwrite coordinates of previously found points with /data= but keep names
89+ points.forEachIndexed { i, point ->
90+ points[i] = point.copy(lat = it[i].lat, lon = it[i].lon)
91+ }
92+ } else {
93+ // Overwrite coordinates of previously found points with /data= including names
94+ points.clear()
95+ points.addAll(it)
96+ }
97+ }
98+ } else if (part.startsWith(' @' )) {
7899 // Center
79100 // /@52.5067296,13.2599309,6z
80- Regex (""" @$LAT ,$LON (?:,${Z } z)?.*""" ).matchEntire(part)?.toLatLonZPoint()?.let { point ->
81- if (point.lat != null && point.lon != null ) {
82- centerCoords = point.lat to point.lon
101+ Regex (""" @$LAT ,$LON (?:,${Z } z)?.*""" ).matchEntire(part)?.toLatLonZPoint()?.also { point ->
102+ val lastPoint = points.lastOrNull()
103+ if (lastPoint == null ) {
104+ // Use center coordinates if we haven't already found a point
105+ points.add(point)
106+ } else if (lastPoint.lat == null && lastPoint.lon == null ) {
107+ // Use center coordinates with the name of the last found point
108+ points[points.size - 1 ] = point.copy(name = lastPoint.name)
109+ } else {
110+ // Don't use center coordinates if we've already found a point with coordinate
83111 }
84112 defaultZ = point.z
85113 }
86- } else {
114+ } else if (part.isNotEmpty()) {
87115 // Coordinates
88116 // /52.492611,13.431726
89- part
90- .takeIf { points.isEmpty() } // Only if a point hasn't already been found, e.g. in /data
91- ?.let { pointPattern.matchEntire(it) }
92- ?.toLatLonPoint()
93- ?.also { points.add(it) }
117+ pointPattern.matchEntire(part)?.toLatLonPoint()?.also { points.add(it) }
94118 // Name
95119 // /Central+Park
96- ? : part
97- .takeIf { defaultName == null } // Use the last name-like path part
98- ?.let { Q_PATH_PATTERN .matchEntire(part) }
99- ?.groupOrNull()
100- ?.also { defaultName = it }
101- }
102- // Once we have a point, name, and z, we can stop iterating path parts
103- if (points.isNotEmpty() && defaultName != null && defaultZ != null ) {
104- return @forEachReversed
120+ ? : points.add(NaivePoint (name = part))
105121 }
106122 }
107- if (points.isEmpty()) {
108- if (centerCoords != null ) {
109- // Use the center point only if we haven't found another point
110- points.add(NaivePoint (centerCoords.first, centerCoords.second))
111- } else if (firstPart in partsThatSupportHtmlParsing) {
112- // Go to HTML parsing if needed
113- htmlUriString = uri.toString()
114- }
115- }
116- } else if (firstPart in partsThatSupportHtmlParsing) {
123+ }
124+ if (points.lastOrNull()?.hasCoordinates() != true && firstPart in partsThatSupportHtmlParsing) {
117125 // Go to HTML parsing if needed
118126 htmlUriString = uri.toString()
119127 }
@@ -158,9 +166,9 @@ object GoogleMapsInput : Input.HasShortUri, Input.HasHtml, Input.HasWeb {
158166 }
159167 if (defaultPoint == null && ! genericMetaTagFound) {
160168 // When the HTML contains a generic "Google Maps" META tag instead of a specific one like
161- // "Berlin - Germany", then it seems that the APP_INITIALIZATION_STATE contains coordinates of the
162- // IP address that the HTTP request came from, instead of correct coordinates . So let's ignore the
163- // coordinates.
169+ // "Berlin - Germany", then it seems that the APP_INITIALIZATION_STATE doesn't contain correct
170+ // coordinates. It contains coordinates of the IP address that the HTTP request came from. So let's
171+ // ignore these coordinates.
164172 defaultPointAppInitStatePattern.find(line)?.toLonLatPoint()?.let {
165173 log.d(" GoogleMapsInput" , " HTML Pattern: Default point pattern 2 matched line $line " )
166174 defaultPoint = it
0 commit comments