コード例 #1
0
        public BitmapImage TileRender(long x, long y, int zoomLevel)
        {
            if (!string.IsNullOrWhiteSpace(_tilePath))
            {
                var q = new QuadKey((int)x, (int)y, zoomLevel);

                var filePath = _tilePath.Replace("{quadkey}", q.Key).Replace("{x}", x.ToString()).Replace("{y}", y.ToString()).Replace("{zoomlevel}", zoomLevel.ToString());

                var fi = new FileInfo(filePath);
                if (fi.Exists)
                {
                    using (var fStream = fi.OpenRead())
                    {
                        var bmp = new BitmapImage();
                        bmp.BeginInit();
                        bmp.StreamSource = fStream;
                        bmp.CacheOption  = BitmapCacheOption.OnLoad;
                        bmp.EndInit();
                        return(bmp);
                    }
                }
            }

            return(CreateTransparentTile());
        }
コード例 #2
0
ファイル: TileController.cs プロジェクト: stenyinGS/utymap
        private void OnPosition(GeoCoordinate geoPosition, Vector3 position, int levelOfDetails)
        {
            // call update logic only if threshold is reached
            if (Vector3.Distance(position, _lastUpdatePosition) > _moveSensitivity || _currentQuadKey.LevelOfDetail != levelOfDetails)
            {
                lock (_lockObj)
                {
                    _lastUpdatePosition = position;
                    _currentQuadKey     = GeoUtils.CreateQuadKey(geoPosition, levelOfDetails);

                    UnloadFarTiles(_currentQuadKey);

                    if (_loadedTiles.ContainsKey(_currentQuadKey))
                    {
                        var tile = _loadedTiles[_currentQuadKey];
                        if (ShouldPreload(tile, position))
                        {
                            PreloadNextTile(tile, position);
                        }
                        return;
                    }

                    Load(_currentQuadKey);
                }
            }
        }
コード例 #3
0
 private bool CheckQuadKey(QuadKey actual, QuadKey expected)
 {
     Assert.AreEqual(expected.LevelOfDetail, actual.LevelOfDetail);
     Assert.AreEqual(expected.TileX, actual.TileX);
     Assert.AreEqual(expected.TileY, actual.TileY);
     return(true);
 }
コード例 #4
0
        private void OnPosition(GeoCoordinate geoPosition, Vector3 position, int levelOfDetails)
        {
            if (!IsValidLevelOfDetails(levelOfDetails))
            {
                throw new ArgumentException(String.Format("Invalid level of details: {0}", levelOfDetails), "levelOfDetails");
            }

            // call update logic only if threshold is reached
            if (Vector3.Distance(position, _lastUpdatePosition) > _moveSensitivity)
            {
                lock (_lockObj)
                {
                    _lastUpdatePosition = position;
                    _currentQuadKey     = GeoUtils.CreateQuadKey(geoPosition, levelOfDetails);

                    UnloadFarTiles(_currentQuadKey);

                    if (_loadedTiles.ContainsKey(_currentQuadKey))
                    {
                        var tile = _loadedTiles[_currentQuadKey];
                        if (ShouldPreload(tile, position))
                        {
                            PreloadNextTile(tile, position);
                        }
                        return;
                    }

                    Load(_currentQuadKey);
                }
            }
        }
コード例 #5
0
ファイル: ViewInfo.cs プロジェクト: inigofu/biketrainer
 public ViewInfo(QuadKey quadKey)
 {
     _width              = 256;
     _height             = 256;
     _topLeftGlobalPixel = new PointF(quadKey.X * 256, quadKey.Y * 256);
     _zoom = quadKey.ZoomLevel;
 }
コード例 #6
0
ファイル: ViewInfo.cs プロジェクト: inigofu/biketrainer
 public ViewInfo(int width, int height, QuadKey quadKey)
 {
     _width              = width;
     _height             = height;
     _topLeftGlobalPixel = new PointF(quadKey.X * 256, quadKey.Y * 256);
     _zoom = quadKey.ZoomLevel;
 }
コード例 #7
0
        /// <inheritdoc />
        protected override string GetUri(QuadKey quadKey)
        {
            var quadKeyToDownload = GetDownloadQuadKey(quadKey);

            return(String.Format(_mapDataServerUri, _mapDataLayers, quadKeyToDownload.LevelOfDetail,
                                 quadKeyToDownload.TileX, quadKeyToDownload.TileY, _mapDataApiKey));
        }
コード例 #8
0
        public void CanAddNode()
        {
            // ARRANGE
            var quadKey        = new QuadKey(0, 0, 6);
            var levelOfDetails = new Range <int>(quadKey.LevelOfDetail, quadKey.LevelOfDetail);
            var node           = new Element(7,
                                             new [] { GeoUtils.QuadKeyToBoundingBox(quadKey).Center() },
                                             new [] { 0.0 },
                                             // NOTE must be corresponding rule in mapcss.
                                             new Dictionary <string, string>()
            {
                { "kind", "locality" }, { "name", "secret place" }
            },
                                             new Dictionary <string, string>());

            // ACT
            _mapDataEditor.Add(MapDataStorageType.InMemory, node, levelOfDetails);

            // ASSERT
            var result = _dataStore.GetResultSync(new Tile(quadKey, _stylesheet, _projection, ElevationDataType.Flat));

            result.Variant.Match(
                e => CompareElements(node, e),
                mesh => { throw new ArgumentException(); });
        }
コード例 #9
0
ファイル: GeoUtils.cs プロジェクト: RagnarDanneskjold/utymap
        public static Rectangle QuadKeyToRect(IProjection projection, QuadKey quadKey)
        {
            var boundingBox = QuadKeyToBoundingBox(quadKey);
            var minPoint = projection.Project(boundingBox.MinPoint, 0);
            var maxPoint = projection.Project(boundingBox.MaxPoint, 0);

            return new Rectangle(minPoint.x, minPoint.z, maxPoint.x - minPoint.x, maxPoint.z - minPoint.z);
        }
コード例 #10
0
ファイル: GeoUtils.cs プロジェクト: vodelerk/utymap
        public static Rectangle QuadKeyToRect(IProjection projection, QuadKey quadKey)
        {
            var boundingBox = QuadKeyToBoundingBox(quadKey);
            var minPoint    = projection.Project(boundingBox.MinPoint, 0);
            var maxPoint    = projection.Project(boundingBox.MaxPoint, 0);

            return(new Rectangle(minPoint.x, minPoint.z, maxPoint.x - minPoint.x, maxPoint.z - minPoint.z));
        }
コード例 #11
0
        /// <summary> Loads tile for given quadKey. </summary>
        private void Load(QuadKey quadKey)
        {
            var tile = new Tile(quadKey, Stylesheet, Projection);

            _loadedTiles.Add(quadKey, tile);

            NotifyOnNextObservers(tile);
        }
コード例 #12
0
        public void CanOnPositionLoadFirstTile()
        {
            QuadKey quadKey = GeoUtils.CreateQuadKey(_worldZeroPoint, LevelOfDetails);

            _tileController.OnPosition(_worldZeroPoint, LevelOfDetails);

            _tileObserver.Verify(o => o.OnNext(It.Is <Tile>(tile => CheckQuadKey(tile.QuadKey, quadKey))));
        }
コード例 #13
0
ファイル: Tile.cs プロジェクト: stenyinGS/utymap
        /// <summary> Creates <see cref="Tile"/>. </summary>
        /// <param name="quadKey"></param>
        /// <param name="stylesheet"></param>
        /// <param name="projection"> Projection. </param>
        public Tile(QuadKey quadKey, Stylesheet stylesheet, IProjection projection)
        {
            QuadKey    = quadKey;
            Stylesheet = stylesheet;
            Projection = projection;

            BoundingBox = GeoUtils.QuadKeyToBoundingBox(quadKey);
            Rectangle   = GeoUtils.QuadKeyToRect(projection, quadKey);
        }
コード例 #14
0
        /// <summary> Get side size in meters of grid consists of 9 quadkeys. </summary>
        private float GetGridHeight(QuadKey quadKey)
        {
            var bbox       = GeoUtils.QuadKeyToBoundingBox(quadKey);
            var bboxHeight = bbox.MaxPoint.Latitude - bbox.MinPoint.Latitude;
            var minPoint   = new GeoCoordinate(bbox.MinPoint.Latitude - bboxHeight, bbox.MinPoint.Longitude);
            var maxPoint   = new GeoCoordinate(bbox.MinPoint.Latitude + bboxHeight, bbox.MaxPoint.Longitude);

            return((float)GeoUtils.Distance(minPoint, maxPoint) * _scale);
        }
コード例 #15
0
ファイル: Tile.cs プロジェクト: RagnarDanneskjold/utymap
        /// <summary> Creates <see cref="Tile"/>. </summary>
        /// <param name="quadKey"></param>
        /// <param name="stylesheet"></param>
        /// <param name="projection"> Projection. </param>
        internal Tile(QuadKey quadKey, Stylesheet stylesheet, IProjection projection)
        {
            QuadKey = quadKey;
            Stylesheet = stylesheet;
            Projection = projection;

            BoundingBox = GeoUtils.QuadKeyToBoundingBox(quadKey);
            Rectangle = GeoUtils.QuadKeyToRect(projection, quadKey);
        }
コード例 #16
0
        /// <inheritdoc />
        protected override string GetUri(QuadKey quadKey)
        {
            var padding     = 0.001;
            var query       = GeoUtils.QuadKeyToBoundingBox(quadKey);
            var queryString = String.Format(_mapDataServerQuery,
                                            query.MinPoint.Latitude - padding, query.MinPoint.Longitude - padding,
                                            query.MaxPoint.Latitude + padding, query.MaxPoint.Longitude + padding);

            return(String.Format("{0}{1}", _mapDataServerUri, Uri.EscapeDataString(queryString)));
        }
コード例 #17
0
        public override Uri GetUri(int x, int y, int zoomLevel)
        {
            var quadKey = new QuadKey(x, y, zoomLevel);

            return(new Uri(
                       String.Format(
                           this.UriFormat,
                           quadKey.Key[quadKey.Key.Length - 1]
                           quadKey.Key,
                           DateTime.Now.ToString("g", System.Globalization.DateTimeFormatInfo.InvariantInfo))));
        }
コード例 #18
0
        public void CanOnPositionLoadNextNorthTile()
        {
            var newQuadKey = new QuadKey(17602, 10743, LevelOfDetails);

            _tileController.OnPosition(_worldZeroPoint, LevelOfDetails);
            _tileObserver.ResetCalls();

            _tileController.OnPosition(MovePosition(_worldZeroPoint, new Vector2(0, 1), 400), LevelOfDetails);

            _tileObserver.Verify(o => o.OnNext(It.Is <Tile>(tile => CheckQuadKey(tile.QuadKey, newQuadKey))));
        }
コード例 #19
0
        /// <summary> Build specific quadkey. </summary>
        private Tile BuildQuadKey(Transform parent, QuadKey quadKey)
        {
            var tileGameObject = new GameObject(quadKey.ToString());

            tileGameObject.transform.parent = parent.transform;
            var tile = CreateTile(quadKey, tileGameObject);

            _loadedQuadKeys.Add(quadKey, tile);
            LoadTile(tile);
            return(tile);
        }
コード例 #20
0
ファイル: TileLoadingTests.cs プロジェクト: vodelerk/utymap
        public void CanLoadTilesAtDetailedLevelOfDetails()
        {
            // ARRANGE
            int lod = 16;

            SetupMapData(TestHelper.BerlinPbfData, lod);
            var count         = 1;
            var centerQuadKey = new QuadKey(35205, 21489, lod);

            // ACT & ASSERT
            TestQuadKeys(centerQuadKey, count, lod);
        }
コード例 #21
0
        public void CanOnPositionUnloadFarTile()
        {
            _configSection.Setup(c => c.GetInt(@"tile/max_tile_distance", It.IsAny <int>())).Returns(1);
            QuadKey quadKey = GeoUtils.CreateQuadKey(_worldZeroPoint, LevelOfDetails);

            for (int i = 0; i < 2; ++i)
            {
                _tileController.OnPosition(MovePosition(_worldZeroPoint, new Vector2(1, 0), i * 400), LevelOfDetails);
            }

            _tileObserver.Verify(o => o.OnNext(It.Is <Tile>(tile => tile.IsDisposed && CheckQuadKey(tile.QuadKey, quadKey))));
        }
コード例 #22
0
        public void CanLoadNextNorthTile()
        {
            var newQuadKey = new QuadKey(17602, 10743, LevelOfDetails);
            _tileController.OnPosition(_worldZeroPoint, LevelOfDetails);
            _tileLoader.ResetCalls();
            _messageBus.ResetCalls();

            _tileController.OnPosition(MovePosition(_worldZeroPoint, new Vector2(0, 1), 400), LevelOfDetails);

            _tileLoader.Verify(t => t.Load(It.Is<Tile>(tile => CheckQuadKey(tile.QuadKey, newQuadKey))));
            _messageBus.Verify(mb => mb.Send(It.Is<TileLoadStartMessage>(m => CheckQuadKey(m.Tile.QuadKey, newQuadKey))));
        }
コード例 #23
0
ファイル: TileLoadingTests.cs プロジェクト: vodelerk/utymap
 private void TestQuadKeys(QuadKey centerQuadKey, int count, int lod)
 {
     for (var y = 0; y < count; ++y)
     {
         for (var x = 0; x < count; ++x)
         {
             var quadKey = new QuadKey(centerQuadKey.TileX + x, centerQuadKey.TileY + y, lod);
             var tile    = new Tile(quadKey, _stylesheet, _projection, ElevationDataType.Flat);
             AssertResult(_mapDataStore.GetResultSync(tile));
         }
     }
     Assert.IsTrue(_isCalled);
 }
コード例 #24
0
ファイル: TileLoadingTests.cs プロジェクト: stenyinGS/utymap
        /// <summary> Loads quadkey waiting for completion callback. </summary>
        private void LoadQuadKeySync(QuadKey quadKey)
        {
            var manualResetEvent = new ManualResetEvent(false);
            var tile             = new Tile(quadKey, _tileController.Stylesheet, _tileController.Projection);

            _mapDataLoader
            .Load(tile)
            .SubscribeOn(Scheduler.CurrentThread)
            .ObserveOn(Scheduler.CurrentThread)
            .Subscribe(AssertData, () => manualResetEvent.Set());

            manualResetEvent.WaitOne();
        }
コード例 #25
0
        /// <summary> Gets childrent for quadkey. </summary>
        private IEnumerable <QuadKey> GetChildren(QuadKey quadKey)
        {
            // TODO can be optimized to avoid string allocations.
            var quadKeyName = quadKey.ToString();

            yield return(QuadKey.FromString(quadKeyName + "0"));

            yield return(QuadKey.FromString(quadKeyName + "1"));

            yield return(QuadKey.FromString(quadKeyName + "2"));

            yield return(QuadKey.FromString(quadKeyName + "3"));
        }
コード例 #26
0
ファイル: GeoUtils.cs プロジェクト: RagnarDanneskjold/utymap
        public static BoundingBox QuadKeyToBoundingBox(QuadKey quadKey)
        {
            int levelOfDetail = quadKey.LevelOfDetail;

            var minPoint = new GeoCoordinate(
                 TileYToLat(quadKey.TileY + 1, levelOfDetail),
                 TileXToLon(quadKey.TileX, levelOfDetail));

            var maxPoint = new GeoCoordinate(
                 TileYToLat(quadKey.TileY, levelOfDetail),
                 TileXToLon(quadKey.TileX + 1, levelOfDetail));

            return new BoundingBox(minPoint, maxPoint);
        }
コード例 #27
0
ファイル: GeoUtils.cs プロジェクト: vodelerk/utymap
        public static BoundingBox QuadKeyToBoundingBox(QuadKey quadKey)
        {
            int levelOfDetail = quadKey.LevelOfDetail;

            var minPoint = new GeoCoordinate(
                TileYToLat(quadKey.TileY + 1, levelOfDetail),
                TileXToLon(quadKey.TileX, levelOfDetail));

            var maxPoint = new GeoCoordinate(
                TileYToLat(quadKey.TileY, levelOfDetail),
                TileXToLon(quadKey.TileX + 1, levelOfDetail));

            return(new BoundingBox(minPoint, maxPoint));
        }
コード例 #28
0
        /// <summary> Builds quadkeys if necessary. Decision is based on visible quadkey and lod level. </summary>
        private void BuildIfNecessary(Transform planet)
        {
            var lod = (int)_zoom;

            var actualGameObject = GetActual(planet, Coordinate, lod);

            if (actualGameObject == planet)
            {
                return;
            }

            var actualQuadKey = QuadKey.FromString(actualGameObject.name);
            var actualName    = actualGameObject.name;

            var parent   = planet;
            var quadKeys = new List <QuadKey>();

            // zoom in
            int disposedTiles = 0;

            if (actualQuadKey.LevelOfDetail < lod)
            {
                quadKeys.AddRange(GetChildren(actualQuadKey));
                var oldParent = actualGameObject.transform.parent;
                disposedTiles = SafeDestroy(actualQuadKey, actualName) ? 1 : 0;

                parent = new GameObject(actualName).transform;
                parent.transform.parent = oldParent;
            }
            // zoom out
            else if (actualQuadKey.LevelOfDetail > lod)
            {
                string name    = actualName.Substring(0, actualName.Length - 1);
                var    quadKey = QuadKey.FromString(name);
                // destroy all siblings
                foreach (var child in GetChildren(quadKey))
                {
                    disposedTiles += SafeDestroy(child, child.ToString()) ? 1 : 0;
                }
                // destroy current as it might be just placeholder.
                SafeDestroy(actualQuadKey, name);
                parent = GetParent(planet, quadKey);
                quadKeys.Add(quadKey);
            }

            UnloadAssets(disposedTiles);
            BuildQuadKeys(parent, quadKeys);
        }
コード例 #29
0
        /// <summary> Destroys gameobject by its name if it exists. </summary>
        private void SafeDestroy(QuadKey quadKey, string name = null)
        {
            if (_loadedQuadKeys.ContainsKey(quadKey))
            {
                _loadedQuadKeys[quadKey].Dispose();
                _loadedQuadKeys.Remove(quadKey);
                return;
            }

            var go = GameObject.Find(name);

            if (go != null)
            {
                Object.Destroy(go);
            }
        }
コード例 #30
0
        /// <summary> Gets parent game object for given quadkey. Creates hierarchy if necessary. </summary>
        private Transform GetParent(Transform planet, QuadKey quadKey)
        {
            // recursion end
            if (quadKey.LevelOfDetail <= LodRange.Minimum)
            {
                return(planet);
            }

            string quadKeyName = quadKey.ToString();
            string parentName  = quadKeyName.Substring(0, quadKeyName.Length - 1);
            var    parent      = GameObject.Find(parentName);

            return(parent != null
                ? parent.transform
                : GetParent(planet, QuadKey.FromString(parentName)));
        }
コード例 #31
0
        void Start()
        {
            // init utymap library
            _compositionRoot = InitTask.Run((container, config) =>
            {
                container
                .Register(Component.For <Stylesheet>().Use <Stylesheet>(@"mapcss/default/index.mapcss"))
                .Register(Component.For <MaterialProvider>().Use <MaterialProvider>())
                .Register(Component.For <GameObjectBuilder>().Use <GameObjectBuilder>())
                .RegisterInstance <IEnumerable <IElementBuilder> >(new List <IElementBuilder>());
            });

            // store map data store reference to member variable
            _mapDataStore = _compositionRoot.GetService <IMapDataStore>();

            // get reference for active stylesheet
            var stylesheet = _compositionRoot.GetService <Stylesheet>();
            // define level of detail
            const int levelOfDetail = 14;
            // create center coordinate;
            var coordinate = (new GeoCoordinate(Latitude, Longitude));
            // create "center" tile
            var center = GeoUtils.CreateQuadKey(coordinate, levelOfDetail);

            // load multiply tiles at once
            for (var tileX = center.TileX - 1; tileX <= center.TileX + 1; ++tileX)
            {
                for (var tileY = center.TileY - 1; tileY <= center.TileY + 1; ++tileY)
                {
                    var quadKey = new QuadKey(tileX, tileY, levelOfDetail);
                    var parent  = new GameObject(quadKey.ToString());
                    parent.transform.SetParent(gameObject.transform);
                    _mapDataStore.OnNext(new Tile(
                                             // quadkey to load.
                                             quadKey,
                                             // provide stylesheet
                                             stylesheet,
                                             // use cartesian projection as we want to build flat world
                                             new CartesianProjection(coordinate),
                                             // use grid elevation: uses mapzen servers by default,
                                             // stores elevation in simple NxN grid format.
                                             ElevationDataType.Grid,
                                             // parent for built game objects
                                             parent));
                }
            }
        }
コード例 #32
0
        private IEnumerable <GeoCoordinate> CreatePolyline(QuadKey quadkey)
        {
            var bbox = GeoUtils.QuadKeyToBoundingBox(quadkey);

            var latStep = (bbox.MaxPoint.Latitude - bbox.MinPoint.Latitude) / _eleGrid;
            var lonStep = (bbox.MaxPoint.Longitude - bbox.MinPoint.Longitude) / _eleGrid;

            for (int i = 0; i < _eleGrid; ++i)
            {
                var lat = bbox.MinPoint.Latitude + i * latStep;
                for (int j = 0; j < _eleGrid; ++j)
                {
                    var lon = bbox.MinPoint.Longitude + j * lonStep;
                    yield return(new GeoCoordinate(lat, lon));
                }
            }
        }
コード例 #33
0
        /// <summary> Removes far tiles from list of loaded and sends corresponding message. </summary>
        private void UnloadFarTiles(QuadKey currentQuadKey)
        {
            var tiles = _loadedTiles.ToArray();

            foreach (var loadedTile in tiles)
            {
                var quadKey = loadedTile.Key;
                if ((Math.Abs(quadKey.TileX - currentQuadKey.TileX) +
                     Math.Abs(quadKey.TileY - currentQuadKey.TileY)) <= _maxTileDistance)
                {
                    continue;
                }

                loadedTile.Value.Dispose();
                _loadedTiles.Remove(quadKey);

                NotifyOnNextObservers(loadedTile.Value);
            }
        }
コード例 #34
0
ファイル: TileLoadingTests.cs プロジェクト: stenyinGS/utymap
        public void CanLoadMultipleTilesAtDetailedLevelOfDetails()
        {
            // ARRANGE
            int lod = 16;

            SetupMapData(TestHelper.BerlinPbfData, lod);
            var count         = 10;
            var centerQuadKey = new QuadKey(35205, 21489, lod);

            // ACT & ASSERT
            for (var y = 0; y < count; ++y)
            {
                for (var x = 0; x < count; ++x)
                {
                    LoadQuadKeySync(new QuadKey(centerQuadKey.TileX + x, centerQuadKey.TileY + y, lod));
                }
            }
            Assert.IsTrue(_isCalled);
        }
コード例 #35
0
        public void CanLoadMultipleTiles()
        {
            // ARRANGE
            SetupMapData(TestHelper.BerlinPbfData);
            var count = 10;
            var centerQuadKey = new QuadKey(35205, 21489, LevelOfDetails);

            // ACT & ASSERT
            for (var y = 0; y < count; ++y)
                for (var x = 0; x < count; ++x)
                {
                    var quadKey = new QuadKey(centerQuadKey.TileX + x, centerQuadKey.TileY + y, LevelOfDetails);
                    var tile = new Tile(quadKey, _tileController.Stylesheet, _tileController.Projection);
                    _mapDataLoader
                        .Load(tile)
                        .SubscribeOn(Scheduler.CurrentThread)
                        .ObserveOn(Scheduler.CurrentThread)
                        .Subscribe(AssertData);
                }
        }
コード例 #36
0
        protected void collectGeometryKeys(QuadMap qmap, QuadKeyList geom_keys)
        {
            // the starting LOD is the best fit the the cell size:
            uint top_lod = getTopLod(qmap, map_layer);

            foreach (MapLayerLevelOfDetail i in map_layer.getLevels())
            {
                MapLayerLevelOfDetail level_def = i;
                uint lod = top_lod + level_def.getDepth();

                // get the extent of tiles that we will build based on the AOI:
                uint cell_xmin, cell_ymin, cell_xmax, cell_ymax;
                qmap.getCells(
                    map_layer.getAreaOfInterest(), lod,
                    cell_xmin, cell_ymin, cell_xmax, cell_ymax);

                for (uint y = cell_ymin; y <= cell_ymax; y++)
                {
                    for (uint x = cell_xmin; x <= cell_xmax; x++)
                    {
                        QuadKey key = new QuadKey(x, y, lod, qmap);
                        for (uint k = 0; k < 4; k++)
                        {
                            geom_keys.push_back(key.createSubKey(k));
                        }
                    }
                }
            }
        }
コード例 #37
0
        protected osg.Node createIntermediateIndexNode(QuadKey key, float min_range, float max_range, SmartReadCallback cb)
        {
            osg.Group group = null;

            for (uint quadrant = 0; quadrant < 4; quadrant++)
            {
                QuadKey subkey = key.createSubKey(quadrant);

                if (osgDB.fileExists(createAbsPathFromTemplate("g" + subkey.toString())))
                {
                    if (!group)
                    {
                        group = new osg.Group();
                        group.setName(key.toString());
                    }

                    //osgGIS.notice() << "QK=" << subkey.toString() << ", Extent=" << subkey.getExtent().toString() << std.endl;

                    // enter the subtile set as a paged index node reference:
                    osg.PagedLOD plod = new osg.PagedLOD();
                    setCenterAndRadius(plod, subkey.getExtent(), reader);

            #if USE_PAGEDLODS_IN_INDEX
            osg.PagedLOD* pointer = new osg.PagedLOD();
            pointer.setFileName( 0, createRelPathFromTemplate( "g" + subkey.toString() ) );
            pointer.setRange( 0, 0, 1e10 );
            pointer.setPriorityScale( 0, 1000.0f ); // top priority, hopefully
            pointer.setPriorityOffset( 0, 1000.0f );
            pointer.setCenter( plod.getCenter() );
            pointer.setRadius( plod.getRadius() );
            #else
                    osg.ProxyNode pointer = new osg.ProxyNode();
                    pointer.setLoadingExternalReferenceMode(osg.ProxyNode.LOAD_IMMEDIATELY);
                    pointer.setFileName(0, createRelPathFromTemplate("g" + subkey.toString()));
                    //setCenterAndRadius( pointer, subkey.getExtent(), reader );
            #endif

                    plod.addChild(pointer, max_range, 1e10);
                    plod.setFileName(1, createRelPathFromTemplate("i" + subkey.toString()));
                    plod.setRange(1, 0, max_range); // last one should always be min=0
                    plod.setPriorityScale(1, MY_PRIORITY_SCALE);

                    group.addChild(plod);

                    //osg.Geode* geode = new osg.Geode();

                    //osg.Sphere* g1 = new osg.Sphere( osg.Vec3(0,0,0), plod.getRadius() );
                    //osg.ShapeDrawable* sd1 = new osg.ShapeDrawable( g1 );
                    //sd1.setColor( osg.Vec4f(1,0,0,.2) );
                    //geode.addDrawable( sd1 );

                    ////osg.Vec3d p = terrain_srs.transform( subkey.getExtent().getCentroid() );
                    ////osg.Vec3d n = p; n.normalize();

                    ////osg.Geometry* g3 = new osg.Geometry();
                    ////osg.Vec3Array* v3 = new osg.Vec3Array(2);
                    ////(*v3)[0] = osg.Vec3d(0,0,0);
                    ////(*v3)[1] = n * 3000.0;
                    ////g3.setVertexArray( v3 );
                    ////osg.Vec4Array* c3 = new osg.Vec4Array(1);
                    ////(*c3)[0].set(1,1,0,1);
                    ////g3.setColorArray( c3 );
                    ////g3.setColorBinding(osg.Geometry.BIND_OVERALL);
                    ////g3.addPrimitiveSet( new osg.DrawArrays(GL_LINES, 0, 2) );
                    ////g3.getOrCreateStateSet().setMode( GL_LIGHTING, osg.StateAttribute.OFF );
                    ////geode.addDrawable( g3 );

                    ////osg.Sphere* g2 = new osg.Sphere( osg.Vec3(0,0,0), 25 );
                    ////osg.ShapeDrawable* sd2 = new osg.ShapeDrawable( g2 );
                    ////sd2.setColor( osg.Vec4f(1,1,0,1) );
                    ////geode.addDrawable( sd2 );

                    ////osg.Matrixd mx = osg.Matrixd.translate( p );
                    //osg.Matrixd mx = osg.Matrixd.translate( plod.getCenter() );
                    //osg.MatrixTransform* mt = new osg.MatrixTransform( mx );

                    //mt.addChild( geode );
                    //mt.getOrCreateStateSet().setMode( GL_BLEND, osg.StateAttribute.ON );
                    //mt.getOrCreateStateSet().setRenderingHint( osg.StateSet.TRANSPARENT_BIN );
                    //group.addChild( mt );
                }
            }

            return group;
        }
コード例 #38
0
        protected osg.Node createLeafIndexNode(QuadKey key, SmartReadCallback cb)
        {
            osg.Group group = null;

            for (uint i = 0; i < 4; i++)
            {
                QuadKey quadrant_key = key.createSubKey(i);

                if (osgDB.fileExists(createAbsPathFromTemplate("g" + quadrant_key.toString())))
                {
                    if (!group)
                    {
                        group = new osg.Group();
                        group.setName(key.toString());
                    }

            #if USE_PAGEDLODS_IN_INDEX
            osg.PagedLOD* pointer = new osg.PagedLOD();
            pointer.setFileName( 0, createRelPathFromTemplate( "g" + quadrant_key.toString() ) );
            pointer.setRange( 0, 0, 1e10 );
            pointer.setPriorityScale( 0, 1000.0f ); // top priority!
            pointer.setPriorityOffset( 0, 1000.0f );
            setCenterAndRadius( pointer, quadrant_key.getExtent(), reader );
            #else
                    osg.ProxyNode pointer = new osg.ProxyNode();
                    pointer.setLoadingExternalReferenceMode(osg.ProxyNode.LOAD_IMMEDIATELY);
                    pointer.setFileName(0, createRelPathFromTemplate("g" + quadrant_key.toString()));
                    //setCenterAndRadius( pointer, quadrant_key.getExtent(), reader );
            #endif

                    group.addChild(pointer);
                }
            }

            return group;
        }
コード例 #39
0
        protected Task createQuadKeyTask(QuadKey key)
        {
            // construct a filter environment template to use for all tasks:
            FilterEnv cell_env = getSession().createFilterEnv();

            cell_env.setTerrainNode(getTerrainNode());
            cell_env.setTerrainSRS(getTerrainSRS());

            string abs_path = createAbsPathFromTemplate("g" + key.toString());

            Task task = null;

            MapLayerLevelOfDetail def = getDefinition(key.createParentKey(), map_layer);
            if (def != null)
            {
                cell_env.setInputSRS(def.getFeatureLayer().getSRS());
                cell_env.setExtent(map_layer.getAreaOfInterest().getSRS().transform(key.getExtent()));
                cell_env.setProperty(new Property("compiler.cell_id", key.toString()));
                foreach (Property i in def.getEnvProperties())
                    cell_env.setProperty(i);

                task = new CellCompiler(
                    key.toString(),
                    abs_path,
                    def.getFeatureLayer(),
                    def.getFilterGraph(),
                    def.getMinRange(),
                    def.getMaxRange(),
                    cell_env,
                    def.getResourcePackager() ? def.getResourcePackager() : resource_packager.get(),
                    getArchive(),
                    def.getUserData());

                // osgGIS.info()
                //    << "Task: Key = " << key.toString() << ", LOD = " << key.getLOD() << ", Extent = " << key.getExtent().toString()
                //    << " (w=" << key.getExtent().getWidth() << ", h=" << key.getExtent().getHeight() << ")"
                //    << std.endl;
            }

            return task;
        }
コード例 #40
0
 static MapLayerLevelOfDetail getDefinition(QuadKey key, MapLayer map_layer)
 {
     uint top_lod = getTopLod(key.getMap(), map_layer);
     uint depth_to_find = key.getLOD() - top_lod;
     foreach (MapLayerLevelOfDetail i in map_layer.getLevels())
     {
         if (i.getDepth() == depth_to_find)
             return i;
     }
     return null;
 }
コード例 #41
0
 /// <summary>
 ///     Adds map data to in-memory storage to specific quadkey.
 ///     Supported formats: shapefile, osm xml, osm pbf.
 /// </summary>
 /// <param name="storageType"> Map data storage. </param>
 /// <param name="stylePath"> Stylesheet path. </param>
 /// <param name="path"> Path to file. </param>
 /// <param name="quadKey"> QuadKey. </param>
 /// <param name="onError"> OnError callback. </param>
 public static void AddToStore(MapStorageType storageType, string stylePath, string path, QuadKey quadKey, OnError onError)
 {
     addToStoreInQuadKey(GetStoreKey(storageType), stylePath, path, quadKey.TileX, quadKey.TileY, quadKey.LevelOfDetail, onError);
 }
コード例 #42
0
        private void OnPosition(GeoCoordinate geoPosition, Vector2 position, int levelOfDetails)
        {
            CurrentMapPoint = position;
            CurrentPosition = geoPosition;

            // call update logic only if threshold is reached
            if (Math.Abs(position.x - _lastUpdatePosition.x) > _moveSensitivity ||
                Math.Abs(position.y - _lastUpdatePosition.y) > _moveSensitivity)
            {
                lock (_lockObj)
                {
                    _lastUpdatePosition = position;

                    _currentQuadKey = GeoUtils.CreateQuadKey(geoPosition, levelOfDetails);

                    if (_loadedTiles.ContainsKey(_currentQuadKey))
                    {
                        var tile = _loadedTiles[_currentQuadKey];
                        if (ShouldPreload(tile, position))
                            PreloadNextTile(tile, position);
                        return;
                    }

                    Load(_currentQuadKey);

                    // TODO add unload old tiles logic
                }
            }
        }
コード例 #43
0
 /// <summary> Loads quadkey. </summary>
 /// <param name="stylePath"> Stylesheet path. </param>
 /// <param name="quadKey"> QuadKey</param>
 /// <param name="onMeshBuilt"></param>
 /// <param name="onElementLoaded"></param>
 /// <param name="onError"></param>
 public static void LoadQuadKey(string stylePath, QuadKey quadKey,
     OnMeshBuilt onMeshBuilt, OnElementLoaded onElementLoaded, OnError onError)
 {
     loadQuadKey(stylePath, quadKey.TileX, quadKey.TileY, quadKey.LevelOfDetail,
         onMeshBuilt, onElementLoaded, onError);
 }
コード例 #44
0
 /// <summary> Checks whether there is data for given quadkey. </summary>
 /// <returns> True if there is data for given quadkey. </returns>
 public static bool HasData(QuadKey quadKey)
 {
     return hasData(quadKey.TileX, quadKey.TileY, quadKey.LevelOfDetail);
 }
コード例 #45
0
 /// <summary> Gets url for given quadkey. </summary>
 protected abstract string GetUrl(QuadKey quadkey);
コード例 #46
0
 /// <summary> Loads tile for given quadKey. </summary>
 private void Load(QuadKey quadKey)
 {
     Tile tile = new Tile(quadKey, Stylesheet, Projection);
     _loadedTiles.Add(quadKey, tile); // TODO remove tile from hashmap if exception is raised
     _messageBus.Send(new TileLoadStartMessage(tile));
     _tileLoader
         .Load(tile)
         .SubscribeOn(Scheduler.ThreadPool)
         .ObserveOn(Scheduler.MainThread)
         .Subscribe(
             u => u.Match(e => _modelBuilder.BuildElement(tile, e), m => _modelBuilder.BuildMesh(tile, m)),
             () => _messageBus.Send(new TileLoadFinishMessage(tile)));
 }
コード例 #47
0
        protected virtual void buildIndex(Profile _profile, osg.Group scene_graph)
        {
            QuadTreeProfile profile = (QuadTreeProfile)_profile;
            if (profile == null) return;

            //osgGIS.notice() << "Rebuilding index..." << std.endl;

            // first, determine the SRS of the output scene graph so that we can
            // make pagedlod/lod centroids.
            SpatialReference output_srs = map_layer.getOutputSRS(getSession(), getTerrainSRS());

            // first build the very top level.
            //scene_graph = new osg.Group();

            // the starting LOD is the best fit the the cell size:
            uint top_lod = getTopLod(profile.getQuadMap(), map_layer);

            SmartReadCallback reader = new SmartReadCallback();

            foreach (MapLayerLevelOfDetail i in map_layer.getLevels())
            {
                MapLayerLevelOfDetail level_def = i;
                uint lod = top_lod + level_def.getDepth();

                MapLayerLevelOfDetail sub_level_def = i + 1 != map_layer.getLevels().end() ? (i + 1).get() : null;
                float min_range, max_range;
                if (sub_level_def != null)
                {
                    min_range = sub_level_def.getMinRange();
                    max_range = sub_level_def.getMaxRange();
                }

                // get the extent of tiles that we will build based on the AOI:
                uint cell_xmin, cell_ymin, cell_xmax, cell_ymax;
                profile.getQuadMap().getCells(
                    map_layer.getAreaOfInterest(), lod,
                    cell_xmin, cell_ymin, cell_xmax, cell_ymax);

                for (uint y = cell_ymin; y <= cell_ymax; y++)
                {
                    for (uint x = cell_xmin; x <= cell_xmax; x++)
                    {
                        osg.Node node;

                        QuadKey key = new QuadKey(x, y, lod, profile.getQuadMap());

                        //osgGIS.notify( osg.NOTICE )
                        //    << "Cell: " << std.endl
                        //    << "   Quadkey = " << key.toString() << std.endl
                        //    << "   LOD = " << key.getLOD() << std.endl
                        //    << "   Extent = " << key.getExtent().toString() << " (w=" << key.getExtent().getWidth() << ", h=" << key.getExtent().getHeight() << ")" << std.endl
                        //    << std.endl;

                        node = sub_level_def ?
                            createIntermediateIndexNode(key, min_range, max_range, reader.get()) :
                            createLeafIndexNode(key, reader);

                        if (node.valid())
                        {
                            string out_file = createAbsPathFromTemplate("i" + key.toString());

                            if (!osgDB.writeNodeFile(*(node.get()), out_file))
                            {
                                // osgGIS.warn() << "FAILED to write index file " << out_file << std.endl;
                            }

                            // at the top level, assemble the root node
                            if (i == map_layer.getLevels().begin())
                            {
                                double top_min_range = sub_level_def != null ? 0 : level_def.getMinRange();

                                osg.PagedLOD plod = new osg.PagedLOD();
                                plod.setName(key.toString());
                                plod.setFileName(0, createRelPathFromTemplate("i" + key.toString()));
                                plod.setRange(0, top_min_range, level_def.getMaxRange());
                                plod.setPriorityScale(0, MY_PRIORITY_SCALE);
                                setCenterAndRadius(plod, key.getExtent(), reader.get());

                                //osgGIS.notice() << "QK=" << key.toString() << ", Ex=" << key.getExtent().toString() << ", Cen=" << key.getExtent().getCentroid().toString() << std.endl;

                                scene_graph.addChild(plod);
                            }
                        }
                    }
                }
            }
        }
コード例 #48
0
 /// <summary> Preloads elevation data for given quadkey. </summary>
 /// <param name="quadKey">Quadkey.</param>
 public static void PreloadElevation(QuadKey quadKey)
 {
     preloadElevation(quadKey.TileX, quadKey.TileY, quadKey.LevelOfDetail);
 }
コード例 #49
0
 private bool CheckQuadKey(QuadKey actual, QuadKey expected)
 {
     Assert.AreEqual(expected.LevelOfDetail, actual.LevelOfDetail);
     Assert.AreEqual(expected.TileX, actual.TileX);
     Assert.AreEqual(expected.TileY, actual.TileY);
     return true;
 }
コード例 #50
0
 /// <inheritdoc />
 protected override string GetUrl(QuadKey quadkey)
 {
     return String.Format(UrlSchema, quadkey);
 }