Short answer: you need to use your own custom SQLite as the base Android library, for example, with other NDK libraries. The tricky part is getting a useful less trivial C # API for the database. Xamarin docs seem to have guides only for simple, simple APIs.
As I'm already used to Java than .NET, I used a combination of the Android Java library (.jar) and the Android native library (.so). The Android Java library already has a Java API shell for the database; this is exactly the same shell that can be used in regular Java Java applications. Of course, technically direct access to the native library from C # is also possible, so java / jar can be excluded from the history. If you know good tools for this, let me know.
- Create a jar binding project for Xamarin, add it to the same solution as your Android project.
- Add jsqlite.jar to the Jars folder of the bindings project. Get it from here: jsqlite.jar
- Add your own libraries (libjsqlite.so and libproj.so) to your application project, create the libs / armeabi folder for this. Get It From The Nutiteq AdvancedMap3D Project
- Define the .so files as AndroidNativeLibrary and set Copy to Output Directory
- Fix binding definitions to remove build errors. Add the project of your bindings to Transforms / Metadata.xml:
<remove-node path="/api/package[@name='jsqlite']/class[@name='Backup']/field[@name='handle']" /> <remove-node path="/api/package[@name='jsqlite']/class[@name='Database']/field[@name='handle']"/> <attr path="/api/package[@name='jsqlite']" name="managedName">jsqlite</attr>
This should generate your working C # API in the SQLite bundle along with Spatialite, Proj.4, and GEOS . The jsqlite DB API itself is different from other C # SQLite APIs, you need to use callback classes. See the following examples. To check module versions:
try { db.Open ("/sdcard/mapxt/estonia-latest-map.sqlite", Constants.SqliteOpenReadonly);
Finally, now request real spatial data using the Nutiteq 3D Maps SDK for Xamarin to render it
// Spatialite query, show results on map // 1. create style and layer for data LineStyle.Builder lineStyleBuilder = new LineStyle.Builder (); lineStyleBuilder.SetColor (NutiteqComponents.Color.Argb(0xff, 0x5C, 0x40, 0x33)); //brown lineStyleBuilder.SetWidth (0.05f); LineStyle lineStyle = lineStyleBuilder.Build (); GeometryLayer geomLayer = new GeometryLayer (view.Layers.BaseLayer.Projection); view.Layers.AddLayer (geomLayer); // 2. do the query, pass results to the layer Database db = new Database (); try { db.Open ("/sdcard/mapxt/estonia-latest-map.sqlite", Constants.SqliteOpenReadonly); // spatial query. Limit to 1000 objects to avoid layer overloading String qry = "SELECT id, HEX(AsBinary(Transform(geometry,3857))), sub_type, name FROM ln_railway LIMIT 1000"; db.Exec (qry, new SpatialQryResult (geomLayer, lineStyle)); } catch (jsqlite.Exception ex) { Log.Error( ex.LocalizedMessage ); } ... // adds query results to given layer, with given style public class SpatialQryResult : Java.Lang.Object, ICallback { GeometryLayer _geomLayer; Style _geomStyle; public SpatialQryResult(GeometryLayer geomLayer, Style geomStyle){ _geomLayer = geomLayer; _geomStyle = geomStyle; } public bool Newrow (string[] rowdata) { string id = rowdata [0]; string geomHex = rowdata [1]; string type = rowdata [2]; string name = rowdata [3]; Label label; if (name != null && name.Length > 1) { label = new DefaultLabel (name, type); } else { label = null; } Geometry[] lineGeoms = WkbRead.ReadWkb(new ByteArrayInputStream(Utils .HexStringToByteArray(geomHex)), rowdata); // following fails if not Line, change for other geometries foreach (Line lineGeom in lineGeoms) { _geomLayer.Add(new Line(lineGeom.VertexList, label, (LineStyle)_geomStyle, _geomLayer)); } return false; } }