Completed
Push — master ( 4ad8b7...b0c1b8 )
by Mark
17s queued 12s
created

helper/search.php (1 issue)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/*
3
 * Copyright (c) 2011-2014 Mark C. Prins <[email protected]>
4
 *
5
 * Permission to use, copy, modify, and distribute this software for any
6
 * purpose with or without fee is hereby granted, provided that the above
7
 * copyright notice and this permission notice appear in all copies.
8
 *
9
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
 */
17
18
/**
19
 * DokuWiki Plugin spatialhelper (Search component).
20
 *
21
 * @license BSD license
22
 * @author  Mark Prins
23
 */
24
class helper_plugin_spatialhelper_search extends DokuWiki_Plugin {
25
    /**
26
     * spatial index.
27
     *
28
     * @var array
29
     */
30
    protected $spatial_idx = array();
31
    /**
32
     * handle to the geoPHP plugin.
33
     */
34
    protected $geophp;
35
    /**
36
     * Precision, Distance of Adjacent Cell in Meters.
37
     *
38
     * @see https://stackoverflow.com/questions/13836416/geohash-and-max-distance
39
     *
40
     * @var float
41
     */
42
    private $precision = array(
43
        5003530,
44
        625441,
45
        123264,
46
        19545,
47
        3803,
48
        610,
49
        118,
50
        19,
51
        3.7,
52
        0.6
53
    );
54
55
    /**
56
     * constructor; initialize/load spatial index.
57
     */
58
    public function __construct() {
59
        // parent::__construct ();
60
        global $conf;
61
62 View Code Duplication
        if(!$geophp = plugin_load('helper', 'geophp')) {
63
            $message = 'helper_plugin_spatialhelper_search::spatialhelper_search: geophp plugin is not available.';
64
            msg($message, -1);
65
        }
66
67
        $idx_dir = $conf ['indexdir'];
68
        if(!@file_exists($idx_dir . '/spatial.idx')) {
69
            $indexer = plugin_load('helper', 'spatialhelper_index');
0 ignored issues
show
$indexer is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
70
        }
71
72
        $this->spatial_idx = unserialize(io_readFile($fn = $idx_dir . '/spatial.idx', false));
73
    }
74
75
    /**
76
     * Find locations based on the coordinate pair.
77
     *
78
     * @param float $lat
79
     *          The y coordinate (or latitude)
80
     * @param float $lon
81
     *          The x coordinate (or longitude)
82
     */
83
    public function findNearbyLatLon(float $lat, float $lon): array {
84
        $geometry = new Point($lon, $lat);
85
        return $this->findNearby($geometry->out('geohash'), $geometry);
86
    }
87
88
    /**
89
     * finds nearby elements in the index based on the geohash.
90
     * returns a list of documents and the bunding box.
91
     *
92
     * @param string $geohash
93
     * @param Point  $p
94
     *          optional point
95
     * @return array of ...
96
     */
97
    public function findNearby(string $geohash, Point $p = null): array {
98
        $_geohashClass = new Geohash();
99
        if(!$p) {
100
            $decodedPoint = $_geohashClass->read($geohash);
101
        } else {
102
            $decodedPoint = $p;
103
        }
104
105
        // find adjacent blocks
106
        $adjacent                 = array();
107
        $adjacent ['center']      = $geohash;
108
        $adjacent ['top']         = $_geohashClass->adjacent($adjacent ['center'], 'top');
109
        $adjacent ['bottom']      = $_geohashClass->adjacent($adjacent ['center'], 'bottom');
110
        $adjacent ['right']       = $_geohashClass->adjacent($adjacent ['center'], 'right');
111
        $adjacent ['left']        = $_geohashClass->adjacent($adjacent ['center'], 'left');
112
        $adjacent ['topleft']     = $_geohashClass->adjacent($adjacent ['left'], 'top');
113
        $adjacent ['topright']    = $_geohashClass->adjacent($adjacent ['right'], 'top');
114
        $adjacent ['bottomright'] = $_geohashClass->adjacent($adjacent ['right'], 'bottom');
115
        $adjacent ['bottomleft']  = $_geohashClass->adjacent($adjacent ['left'], 'bottom');
116
        dbglog($adjacent, "adjacent geo hashes:");
117
118
        // find all the pages in the index that overlap with the adjacent hashes
119
        $docIds = array();
120
        foreach($adjacent as $adjHash) {
121
            if(is_array($this->spatial_idx)) {
122
                foreach($this->spatial_idx as $_geohash => $_docIds) {
123
                    if(strpos($_geohash, $adjHash) !== false) {
124
                        // dbglog ( "Found adjacent geo hash: $adjHash in $_geohash" );
125
                        // if $adjHash similar to geohash
126
                        $docIds = array_merge($docIds, $_docIds);
127
                    }
128
                }
129
            }
130
        }
131
        $docIds = array_unique($docIds);
132
        dbglog($docIds, "found docIDs");
133
134
        // create associative array of pages + calculate distance
135
        $pages   = array();
136
        $media   = array();
137
        $indexer = plugin_load('helper', 'spatialhelper_index');
138
139
        foreach($docIds as $id) {
140
            if(strpos($id, 'media__', 0) === 0) {
141
                $id = substr($id, strlen('media__'));
142
                if(auth_quickaclcheck($id) >= /*AUTH_READ*/ 1) {
143
                    $point    = $indexer->getCoordsFromExif($id);
144
                    $line     = new LineString(
145
                        [
146
                            $decodedPoint,
147
                            $point
148
                        ]
149
                    );
150
                    $media [] = array(
151
                        'id'       => $id,
152
                        'distance' => (int) ($line->greatCircleLength()),
153
                        'lat'      => $point->y(),
154
                        'lon'      => $point->x()
155
                        // optionally add other meta such as tag, description...
156
                    );
157
                }
158
            } else {
159
                if(auth_quickaclcheck($id) >= /*AUTH_READ*/ 1) {
160
                    $geotags  = p_get_metadata($id, 'geo');
161
                    $point    = new Point($geotags ['lon'], $geotags ['lat']);
162
                    $line     = new LineString(
163
                        [
164
                            $decodedPoint,
165
                            $point
166
                        ]
167
                    );
168
                    $pages [] = array(
169
                        'id'          => $id,
170
                        'distance'    => (int) ($line->greatCircleLength()),
171
                        'description' => p_get_metadata($id, 'description')['abstract'],
172
                        'lat'         => $geotags ['lat'],
173
                        'lon'         => $geotags ['lon']
174
                        // optionally add other meta such as tag...
175
                    );
176
                }
177
            }
178
        }
179
180
        // sort all the pages/media using distance
181
        usort(
182
            $pages, static function ($a, $b) {
183
            return strnatcmp($a ['distance'], $b ['distance']);
184
        }
185
        );
186
        usort(
187
            $media, static function ($a, $b) {
188
            return strnatcmp($a ['distance'], $b ['distance']);
189
        }
190
        );
191
192
        return array(
193
            'pages'     => $pages,
194
            'media'     => $media,
195
            'lat'       => $decodedPoint->y(),
196
            'lon'       => $decodedPoint->x(),
197
            'geohash'   => $geohash,
198
            'precision' => $this->precision [strlen($geohash)]
199
        );
200
    }
201
}
202