1 /******************************************************************************
2 * Copyright (c) 2018, Kyle Mann (kyle@hobu.co)
3 *
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following
8 * conditions are met:
9 *
10 *     * Redistributions of source code must retain the above copyright
11 *       notice, this list of conditions and the following disclaimer.
12 *     * Redistributions in binary form must reproduce the above copyright
13 *       notice, this list of conditions and the following disclaimer in
14 *       the documentation and/or other materials provided
15 *       with the distribution.
16 *     * Neither the name of Hobu, Inc. or Flaxen Geo Consulting nor the
17 *       names of its contributors may be used to endorse or promote
18 *       products derived from this software without specific prior
19 *       written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
32 * OF SUCH DAMAGE.
33 ****************************************************************************/
34 
35 #pragma once
36 
37 #include <vector>
38 #include <list>
39 #include <map>
40 #include <queue>
41 #include <mutex>
42 #include <condition_variable>
43 
44 #include <arbiter/arbiter.hpp>
45 
46 #include <pdal/Reader.hpp>
47 #include <pdal/Streamable.hpp>
48 #include <pdal/Streamable.hpp>
49 #include <pdal/util/Bounds.hpp>
50 
51 #include "EsriUtil.hpp"
52 #include "PageManager.hpp"
53 
54 namespace pdal
55 {
56 
57 class SrsTransform;
58 class ThreadPool;
59 
60 class PDAL_DLL EsriReader : public Reader, public Streamable
61 {
62 public:
63     EsriReader();
64     ~EsriReader();
65 
66 protected:
67     std::unique_ptr<arbiter::Arbiter> m_arbiter;
68 
69     virtual NL::json initInfo() = 0;
70     virtual std::vector<char> fetchBinary(std::string url, std::string attNum,
71             std::string ext) const = 0;
72     virtual std::string fetchJson(std::string) = 0;
73 
74 private:
75     struct Args;
76     struct DimData;
77     class TileContents;
78 
79     std::unique_ptr<Args> m_args;
80     NL::json m_info;
81     int m_nodeCap;
82     i3s::Version m_version;
83     SpatialReference m_nativeSrs;
84     std::unique_ptr<i3s::PageManager> m_pageManager;
85     std::unique_ptr<SrsTransform> m_ecefTransform;
86     std::unique_ptr<ThreadPool> m_pool;
87     std::vector<DimData> m_esriDims;
88     size_t m_extraDimCount;
89     std::vector<int> m_nodes;
90     size_t m_curNodeIdx;
91     size_t m_tilesToProcess;
92     PointId m_pointId;
93     std::queue<TileContents, std::list<TileContents>> m_contents;
94     std::unique_ptr<TileContents> m_currentTile;
95     mutable std::mutex m_mutex;
96     mutable std::condition_variable m_contentsCv;
97 
98     virtual void addArgs(ProgramArgs& args) override;
99     virtual void initialize(PointTableRef table) override;
100     virtual void addDimensions(PointLayoutPtr layout) override;
101     virtual void ready(PointTableRef table) override;
102     virtual point_count_t read(PointViewPtr view, point_count_t count) override;
103     virtual bool processOne(PointRef&) override;
104     void createView(std::string localUrl, int nodeIndex,  PointView& view);
105     void traverseTree(i3s::PagePtr page, int node);
106     void load(int nodeId);
107     TileContents loadPath(const std::string& url);
108     void checkTile(const TileContents& tile);
109     void process(PointViewPtr dstView, const TileContents& tile,
110         point_count_t count);
111     bool processPoint(PointRef& dst, const TileContents& tile);
112 };
113 
114 } // namespace pdal
115 
116