/// <summary> Adds tree to in-memory tree. </summary> private void AddTree() { // NOTE use case 3: lets add some conifer tree on the road // create an element which represents a tree Element tree = new Element( // id of the object 0, // geo coordinate of the object new[] { new GeoCoordinate(52.53150, 13.38724) }, // height in meters under sea new [] { .0 }, // map data tags new Dictionary <string, string> { { "natural", "tree" }, { "type", "conifer" } }, // styles: ignored by editor new Dictionary <string, string>()); _compositionRoot .GetService <IMapDataEditor>() .Add( // type of storage MapDataStorages.TransientStorageKey, // element to store tree, // LOD range where element is stored new Range <int>(16, 16)); }
/// <summary> Builds instance responsible for composing object graph. </summary> private static CompositionRoot BuildCompositionRoot(Action <IContainer, IConfigSection> action, ITrace trace) { // create entry point for library functionallity using default configuration overriding some properties var root = new CompositionRoot(new Container(), ConfigBuilder.GetDefault().SetIndex("index").Build()) // override library's default services with demo specific implementations .RegisterAction((container, config) => { container .RegisterInstance <ITrace>(trace) .Register(Component.For <IPathResolver>().Use <UnityPathResolver>()) .Register(Component.For <INetworkService>().Use <UnityNetworkService>()) .Register(Component.For <IMapDataLibrary>().Use <MapDataLibrary>()); }) // override with scene specific implementations .RegisterAction(action) // setup object graph .Setup(); // Register default data storages: one keeps data on disk, another one - in memory. // You are not limited with these two: you can add more disk and/or memory storages. // NOTE First registered storage will be used to save map data received from downloaded data var mapDataStore = root.GetService <IMapDataStore>(); mapDataStore.Register(MapDataStorages.PersistentStorageKey, @"index/data"); mapDataStore.Register(MapDataStorages.TransientStorageKey); // Enable mesh caching. root.GetService <IMapDataLibrary>().EnableCache(); return(root); }
void Start() { _compositionRoot = MapInitTask.Run(); var mapDataStore = _compositionRoot.GetService <IMapDataStore>(); var stylesheet = _compositionRoot.GetService <Stylesheet>(); var materialProvider = _compositionRoot.GetService <MaterialProvider>(); var startCoord = new GeoCoordinate(StartLatitude, StartLongitude); // scaled radius of Earth in meters, approx. 1:1000 const float planetRadius = 6371f; const float surfaceScale = 0.01f; const float detailScale = 1f; _lods = new List <Range <int> > { new Range <int>(1, 8), new Range <int>(9, 15), new Range <int>(16, 16) }; var sphereController = new SphereTileController(mapDataStore, stylesheet, ElevationDataType.Flat, Pivot, _lods[0], planetRadius); var surfaceController = new SurfaceTileController(mapDataStore, stylesheet, ElevationDataType.Flat, Pivot, _lods[1], startCoord, surfaceScale, 1000); var detailController = new SurfaceTileController(mapDataStore, stylesheet, ElevationDataType.Flat, Pivot, _lods[2], startCoord, detailScale, 500); var sphereGestures = new SphereGestureStrategy(sphereController, TwoFingerMoveGesture, ManipulationGesture, planetRadius); var surfaceGestures = new SurfaceGestureStrategy(surfaceController, TwoFingerMoveGesture, ManipulationGesture); var detailGestures = new SurfaceGestureStrategy(detailController, TwoFingerMoveGesture, ManipulationGesture); _spaces = new List <Space> { new SphereSpace(sphereController, sphereGestures, Planet, materialProvider), new SurfaceSpace(surfaceController, surfaceGestures, Surface, materialProvider), new SurfaceSpace(detailController, detailGestures, Surface, materialProvider) }; DoTransition(startCoord, StartZoom); }
public void Setup() { _compositionRoot = TestHelper.GetCompositionRoot(TestHelper.WorldZeroPoint); _mapDataEditor = _compositionRoot.GetService <IMapDataEditor>(); _dataStore = _compositionRoot.GetService <IMapDataStore>(); _stylesheet = _compositionRoot.GetService <Stylesheet>(); _projection = _compositionRoot.GetService <IProjection>(); }
/// <summary> Setup test map data. </summary> private void SetupMapData() { var mapDataLoader = _compositionRoot.GetService <IMapDataLoader>(); var stylesheet = _compositionRoot.GetService <Stylesheet>(); mapDataLoader.AddToStore(MapStorageType.InMemory, TestHelper.BerlinXmlData, stylesheet, new Range <int>(LevelOfDetails, LevelOfDetails)); }
public void Setup() { _compositionRoot = TestHelper.GetCompositionRoot(TestHelper.WorldZeroPoint, (container, _) => container.Register(Component.For<IElevationProvider>().Use<FlatElevationProvider>())); _elementEditor = _compositionRoot.GetService<IElementEditor>(); _dataLoader = _compositionRoot.GetService<IMapDataLoader>(); _stylesheet = _compositionRoot.GetService<Stylesheet>(); _projection = _compositionRoot.GetService<IProjection>(); }
public void Setup() { _compositionRoot = TestHelper.GetCompositionRoot(TestHelper.WorldZeroPoint, (container, _) => container.Register(Component.For <IElevationProvider>().Use <FlatElevationProvider>())); _elementEditor = _compositionRoot.GetService <IElementEditor>(); _dataLoader = _compositionRoot.GetService <IMapDataLoader>(); _stylesheet = _compositionRoot.GetService <Stylesheet>(); _projection = _compositionRoot.GetService <IProjection>(); }
void Start() { // init utymap library _compositionRoot = InitTask.Run((container, config) => { container .Register(Component.For <Stylesheet>().Use <Stylesheet>(@"mapcss/ground/ground.mapcss")) .Register(Component.For <MaterialProvider>().Use <MaterialProvider>()) .Register(Component.For <GameObjectBuilder>().Use <GameObjectBuilder>()) .Register(Component.For <IGeocoder>().Use <UtyMapGeocoder>()) .Register(Component.For <IElementBuilder>().Use <PlaceElementBuilder>().Named("place")); }); // initial geo position and quad key of character var coordinate = new GeoCoordinate(StartLatitude, StartLongitude); var quadKey = GeoUtils.CreateQuadKey(coordinate, LevelOfDetail); // init address controller which is responsible for searching address _addressController = new AddressController( _compositionRoot.GetService <IGeocoder>(), Text.GetComponent <Text>()); // init tile controller which is responsible for tile processing _tileController = new TileController( _compositionRoot.GetService <IMapDataStore>(), _compositionRoot.GetService <Stylesheet>(), ElevationType, coordinate, LevelOfDetail); // freeze target till initial tile is loaded var rigidbody = CharacterTarget.transform.GetComponent <Rigidbody>(); rigidbody.isKinematic = true; // TODO unsubscribe listener _compositionRoot .GetService <IMapDataStore>() .ObserveOn <Tile>(Scheduler.MainThread) .Subscribe(tile => { if (!quadKey.Equals(tile.QuadKey)) { return; } // get elevation at current position var elevation = _compositionRoot .GetService <IMapDataLibrary>() .GetElevation(ElevationType, quadKey, coordinate); // move character accordingly CharacterTarget.transform.localPosition = new Vector3( CharacterTarget.transform.localPosition.x, (float)elevation + 5f, CharacterTarget.transform.localPosition.z); rigidbody.isKinematic = false; }); }
public void Setup() { // initialize services _compositionRoot = TestHelper.GetCompositionRoot(_worldZeroPoint); // get local references _mapDataLoader = _compositionRoot.GetService<IMapDataLoader>(); _tileController = _compositionRoot.GetService<ITileController>(); }
public void Setup() { // initialize services _compositionRoot = TestHelper.GetCompositionRoot(_worldZeroPoint); // get local references _mapDataLoader = _compositionRoot.GetService <IMapDataLoader>(); _tileController = _compositionRoot.GetService <ITileController>(); _isCalled = false; }
public void Setup() { // initialize services _compositionRoot = TestHelper.GetCompositionRoot(_worldZeroPoint); _stylesheet = _compositionRoot.GetService <Stylesheet>(); _projection = _compositionRoot.GetService <IProjection>(); // get local references _mapDataStore = _compositionRoot.GetService <IMapDataStore>(); _isCalled = false; }
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>(); // for demo purpose, disable mesh caching to force import data into memory for every run _compositionRoot.GetService <IMapDataLibrary>().DisableCache(); // get reference for active stylesheet. var stylesheet = _compositionRoot.GetService <Stylesheet>(); // get reference to trace. var trace = _compositionRoot.GetService <ITrace>(); // create tile which represents target region to load. var tile = new Tile( // create quadkey using coordinate and choose proper LOD GeoUtils.CreateQuadKey(_coordinate, Scene == SceneType.Bird ? 14 : 16), // provide stylesheet (used to be the same as for import) stylesheet, // use cartesian projection as we want to build flat world new CartesianProjection(_coordinate), // use flat elevation (all vertices have zero meters elevation) ElevationDataType.Flat, // parent for built game objects gameObject); // import data into memory _mapDataStore.AddTo( // define where geoindex is created (in memory, not persistent) MapDataStorages.TransientStorageKey, // path to map data String.Format(MapDataPathFormat, Scene == SceneType.Bird ? "json" : "xml"), // stylesheet is used to import only used data and skip unused stylesheet, // level of detail (zoom) for which map data should be imported new Range <int>(16, 16), new CancellationToken()) // start import and listen for events. .Subscribe( // NOTE progress callback is ignored (progress) => { }, // exception is reported (exception) => trace.Error("import", exception, "Cannot import map data"), // once completed, load the corresponding tile () => _mapDataStore.OnNext(tile)); }
/// <summary> Starts listening for mapdata from core library to convert it into unity game objects. </summary> private static void SubscribeOnMapData(CompositionRoot compositionRoot, ITrace trace) { const string traceCategory = "mapdata"; var modelBuilder = compositionRoot.GetService <UnityModelBuilder>(); compositionRoot.GetService <IMapDataStore>() .SubscribeOn <MapData>(Scheduler.ThreadPool) .ObserveOn(Scheduler.MainThread) .Where(r => !r.Tile.IsDisposed) .Subscribe(r => r.Variant.Match( e => modelBuilder.BuildElement(r.Tile, e), m => modelBuilder.BuildMesh(r.Tile, m)), ex => trace.Error(traceCategory, ex, "cannot process mapdata."), () => trace.Warn(traceCategory, "stop listening mapdata.")); }
public static CompositionRoot GetCompositionRoot(GeoCoordinate worldZeroPoint, Action <IContainer, IConfigSection> action) { // create default container which should not be exposed outside // to avoid Service Locator pattern. IContainer container = new Container(); // create default application configuration var config = ConfigBuilder.GetDefault() .SetIndex(IndexPath) .Build(); // initialize services var root = new CompositionRoot(container, config) .RegisterAction((c, _) => c.Register(Component.For <ITrace>().Use <ConsoleTrace>())) .RegisterAction((c, _) => c.Register(Component.For <IPathResolver>().Use <TestPathResolver>())) .RegisterAction((c, _) => c.Register(Component.For <Stylesheet>().Use <Stylesheet>(DefaultMapCss))) .RegisterAction((c, _) => c.Register(Component.For <IProjection>().Use <CartesianProjection>(worldZeroPoint))) .RegisterAction(action) .Setup(); // Register default data stores to simplify test setup. The order is important var mapDataStore = root.GetService <IMapDataStore>(); mapDataStore.Register(TransientStorageKey); mapDataStore.Register(PersistentStorageKey, IndexPath + "/data"); return(root); }
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)); } } }
/// <summary> Setup test map data. </summary> private void SetupMapData(string mapDataPath, int lod) { var range = new Range <int>(lod, lod); _compositionRoot .GetService <IMapDataStore>() .AddTo(TestHelper.TransientStorageKey, mapDataPath, _stylesheet, range, new CancellationToken()); }
/// <summary> Setup test map data. </summary> private void SetupMapData(string mapDataPath, int lod) { var range = new Range <int>(lod, lod); _compositionRoot .GetService <IMapDataStore>() .Add(MapDataStorageType.InMemory, mapDataPath, _stylesheet, range); }
/// <summary> Setup test map data. </summary> private void SetupMapData(string mapDataPath, int lod) { var range = new Range <int>(lod, lod); _compositionRoot .GetService <IMapDataLoader>() .AddToStore(MapStorageType.InMemory, mapDataPath, _tileController.Stylesheet, range); }
void Start() { _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>()) .Register(Component.For <IElementBuilder>().Use <LabelElementBuilder>().Named("label")); }); var mapDataStore = _compositionRoot.GetService <IMapDataStore>(); var stylesheet = _compositionRoot.GetService <Stylesheet>(); var materialProvider = _compositionRoot.GetService <MaterialProvider>(); var startCoord = new GeoCoordinate(StartLatitude, StartLongitude); // scaled radius of Earth in meters, approx. 1:1000 const float planetRadius = 6371f; const float surfaceScale = 0.01f; const float detailScale = 1f; _lods = new List <Range <int> > { new Range <int>(1, 8), new Range <int>(9, 15), new Range <int>(16, 16) }; var sphereController = new SphereTileController(mapDataStore, stylesheet, ElevationDataType.Flat, Pivot, _lods[0], planetRadius); var surfaceController = new SurfaceTileController(mapDataStore, stylesheet, ElevationDataType.Flat, Pivot, _lods[1], startCoord, surfaceScale, 1000); var detailController = new SurfaceTileController(mapDataStore, stylesheet, ElevationDataType.Flat, Pivot, _lods[2], startCoord, detailScale, 500); var sphereGestures = new SphereGestureStrategy(sphereController, TwoFingerMoveGesture, ManipulationGesture, planetRadius); var surfaceGestures = new SurfaceGestureStrategy(surfaceController, TwoFingerMoveGesture, ManipulationGesture); var detailGestures = new SurfaceGestureStrategy(detailController, TwoFingerMoveGesture, ManipulationGesture); _spaces = new List <Space> { new SphereSpace(sphereController, sphereGestures, Planet, materialProvider), new SurfaceSpace(surfaceController, surfaceGestures, Surface, materialProvider), new SurfaceSpace(detailController, detailGestures, Surface, materialProvider) }; DoTransition(startCoord, StartZoom); }
void Start() { // init utymap library _compositionRoot = InitTask.Run((container, config) => { container // NOTE use another mapcss style .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>()); }); // get trace for logging. _trace = _compositionRoot.GetService <ITrace>(); // store map data store reference to member variable _mapDataStore = _compositionRoot.GetService <IMapDataStore>(); // disable mesh caching to force import data into memory for every run _compositionRoot.GetService <IMapDataLibrary>().DisableCache(); // import data into memory _mapDataStore.AddTo( // define where geoindex is created (in memory, not persistent) MapDataStorages.TransientStorageKey, // path to map data MapDataPath, // stylesheet is used to import only used data and skip unused _compositionRoot.GetService <Stylesheet>(), // level of detail (zoom) for which map data should be imported _range, new CancellationToken()) // start import and listen for events. .Subscribe( // NOTE progress callback is ignored (progress) => { }, // exception is reported (exception) => _trace.Error("search", exception, "Cannot import map data"), // once completed, load the corresponding tile OnDataImported); }
void Start() { // init utymap library _compositionRoot = InitTask.Run((container, config) => { container // NOTE use another mapcss style .Register(Component.For <Stylesheet>().Use <Stylesheet>(@"mapcss/customization/customization.mapcss")) .Register(Component.For <MaterialProvider>().Use <MaterialProvider>()) .Register(Component.For <GameObjectBuilder>().Use <GameObjectBuilder>()) // NOTE for use case 1: put cubes for POI .Register(Component.For <IElementBuilder>().Use <PlaceElementBuilder>().Named("place")) // NOTE for use case 2: search for capsule object in scene which replaces specific tree .Register(Component.For <IElementBuilder>().Use <ImportElementBuilder>().Named("import")); }); // store map data store reference to member variable _mapDataStore = _compositionRoot.GetService <IMapDataStore>(); // disable mesh caching to force import data into memory for every run _compositionRoot.GetService <IMapDataLibrary>().DisableCache(); // import data into memory _mapDataStore.AddTo( // define where geoindex is created (in memory, not persistent) MapDataStorages.TransientStorageKey, // path to map data MapDataPath, // stylesheet is used to import only used data and skip unused _compositionRoot.GetService <Stylesheet>(), // level of detail (zoom) for which map data should be imported new Range <int>(16, 16), new CancellationToken()) // start import and listen for events. .Subscribe( // NOTE progress callback is ignored (progress) => { }, // exception is reported (exception) => _compositionRoot.GetService <ITrace>().Error("import", exception, "Cannot import map data"), // once completed, load the corresponding tile OnDataImported); }
private void Initialize() { // initialize services _compositionRoot = TestHelper.GetCompositionRoot(_worldZeroPoint); // get local references _messageBus = _compositionRoot.GetService <IMessageBus>(); _trace = _compositionRoot.GetService <ITrace>(); _tileController = _compositionRoot.GetService <ITileController>(); SetupMapData(); // set observer to react on geo position changes _messageBus.AsObservable <GeoPosition>() .ObserveOn(Scheduler.MainThread) .Subscribe(position => { _trace.Debug(TraceCategory, "GeoPosition: {0}", position.ToString()); _tileController.OnPosition(position.Coordinate, LevelOfDetails); }); }
private void Initialize() { // initialize services _compositionRoot = TestHelper.GetCompositionRoot(_worldZeroPoint); // get local references _messageBus = _compositionRoot.GetService<IMessageBus>(); _trace = _compositionRoot.GetService<ITrace>(); _tileController = _compositionRoot.GetService<ITileController>(); SetupMapData(); // set observer to react on geo position changes _messageBus.AsObservable<GeoPosition>() .ObserveOn(Scheduler.MainThread) .Subscribe(position => { _trace.Debug(TraceCategory, "GeoPosition: {0}", position.ToString()); _tileController.OnPosition(position.Coordinate, LevelOfDetails); }); }
/// <summary> Loads tile. </summary> private void LoadTile() { _mapDataStore.OnNext(new Tile( // create quadkey using coordinate and LOD GeoUtils.CreateQuadKey(_coordinate, _range.Maximum), // provide stylesheet _compositionRoot.GetService <Stylesheet>(), // use cartesian projection as we want to build flat world new CartesianProjection(_coordinate), // use flat elevation (all vertices have zero meters elevation) ElevationDataType.Flat, // parent for built game objects gameObject)); }