Geography: one of the identified items was in an invalid format – Entity Framework

Hey everyone,

I’m currently working on a prototype using .net core, sql server, ef and NetTopologySuite to handle locations. While trying to save a location I ran into the following error:

Geography: one of the identified items was in an invalid format

My code was as follows:

using GeoAPI.Geometries;
using NetTopologySuite;
using NetTopologySuite.Geometries;

...
var geometryFactory = NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326);
...
Location = geometryFactory.CreatePoint(new Coordinate(request.Lat, request.Lng))
...

The solution ended up being pretty straight-forward. Simply swap the latitude and longitude values when creating a coordinate:

Location = geometryFactory.CreatePoint(new Coordinate(request.Lat, request.Lng))

// Use this instead
Location = geometryFactory.CreatePoint(new Coordinate(request.Lng, request.Lat))

This is mentioned pretty clearly when reading the documents but I somehow skipped over it. Hopefully this will be able to help out anyone else who does the same thing!

Official docs: https://docs.microsoft.com/sv-se/ef/core/modeling/spatial

Simple React-Leaflet Location Picker Setup

Hi everyone,

Just thought I’d share a very simple react-leaflet setup in case it’s able to help anyone.

screencast-localhost_3889-2019.08.24-14_01_41.gif

Add the css and javascript for leaflet to public > index.html:

  
https://unpkg.com/leaflet@1.5.1/dist/leaflet.js">https://unpkg.com/leaflet@1.5.1/dist/leaflet.js

Install react-leaflet via npm or yarn, also add the dependencies:

npm install react-leaflet # npm
npm install leaflet react react-dom # npm

yarn add react-leaflet # Yarn
yarn add leaflet react react-dom # Yarn

Create the map component:

import React, { useState } from 'react'
import { Map, TileLayer, Marker, Popup } from 'react-leaflet'


const MapSimple = () => {

    const [location, setLocation] = useState({
        lat: 51.505,
        lng: -0.09,
        zoom: 13,
    });
    const position = [location.lat, location.lng];
    
    const setMarkerPosition = e => {
        setLocation({ ...e.latlng, zoom: 19 });
        console.log(`My location is: ${JSON.stringify(e.latlng, null, 3)}`)
    };

    return (
        
            <TileLayer
                attribution='© OpenStreetMap contributors'
                url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
            />
            
                
                   A sample popup.
                
            
        
    )
}

export default MapSimple;

Request Denied – react-geocode

Hi everyone,

I’m currently testing react-geocode but hit a “request denied” error after providing my API key.

Error: Server returned status code REQUEST_DENIED

The solution was pretty simple thankfully – enable the Geocoding API for your project: https://developers.google.com/maps/documentation/geocoding/get-api-key

In my case I was re-using a Google maps key from another project where I’d enabled all of the map apis but not the GeoCoding one.

Module not found: Can’t resolve ‘leaflet’ in – react-leaflet error

Hey everyone,

I ran into the following error after installing react-leaflet and attempting to run an example:

Module not found: Can’t resolve ‘leaflet’ in ‘…\node_modules\react-leaflet\es’

It turned out I’d simply rushed things and skipped the second step in the documentation:

npm install leaflet react react-dom # npm
yarn add leaflet react react-dom # Yarn

Doco: https://react-leaflet.js.org/docs/en/installation.html

NetTopologySuite Circular Reference with .net core 2.2

Hey everyone,

Testing out a spatial project with .net core and I ran into the following error:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException : The best overloaded method match for ‘Xunit.Assert.Equal(string, string)’ has some invalid arguments

at CallSite.Target(Closure , CallSite , Type , Nullable`1 , Object )
at UpdateDelegates.UpdateAndExecuteVoid3[T0,T1,T2](CallSite site, T0 arg0, T1 arg1, T2 arg2)
at DiscussionsControllerIntegrationTests.CreateTestDiscussion(HttpClient client, ApplicationDbContext db, DiscussionCreateWebRequest payload) in DiscussionsControllerIntegrationTests.cs line: 56
at DiscussionsControllerIntegrationTests.b__1_0(ApplicationDbContext db) in DiscussionsControllerIntegrationTests.cs line: 27
at IntegrationTestBase.RunTest(Func`2 testToExecute) in IntegrationTestBase.cs line: 54
at DiscussionsControllerIntegrationTests.CreateDiscussionIsSuccessful() in DiscussionsControllerIntegrationTests.cs line: 25
at — End of stack trace from previous location where exception was thrown —

Thankfully the solution is pretty straight forward. Install GeoJSON:

Install-Package NetTopologySuite.IO.GeoJSON

Then merge the following with your existing addMvc call in startup.cs:

services.AddMvc(options =>
            {
                // Prevent the following exception: 'This method does not support GeometryCollection arguments'
                // See: https://github.com/npgsql/Npgsql.EntityFrameworkCore.PostgreSQL/issues/585
                options.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(Point)));
                options.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(Coordinate)));
                options.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(LineString)));
                options.ModelMetadataDetailsProviders.Add(new SuppressChildValidationMetadataProvider(typeof(MultiLineString)));
            })
                .AddJsonOptions(options =>
                {
                    foreach (var converter in NetTopologySuite.IO.GeoJsonSerializer.Create(new GeometryFactory(new PrecisionModel(), 4326)).Converters)
                    {
                        options.SerializerSettings.Converters.Add(converter);
                    }
                })
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

Set Date Back Twelve Hours – MSSQL

Hey everyone,

A quick post on how to set a date value for twelve hours ago using SQL Server:

UPDATE MyTable
SET MyDate = dateadd(HOUR, -12, CURRENT_TIMESTAMP)

Simply use the dateadd function and specify the unit (hours in this case). The example above will set MyDate to twelve hours ago.

Here’s the offical documentation on the function: https://docs.microsoft.com/en-us/sql/t-sql/functions/dateadd-transact-sql?view=sql-server-2017

Also, thanks to this stackoverflow post for the info: https://stackoverflow.com/a/18518412/522859

Unable to Migrate after Adding Config to Startup

Hi everyone,

Just a quick post on fixing up a migration error after I added new config to startup.cs via DI. The error after running add-migration was pretty unintuitive:

Unable to create an object of type 'ApplicationDbContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728

To find out a bit more I ran the following:

add-migration -verbose

This revealed the fact that there was an issue with adding my config line. The error stated that I had to have an empty constructor which led me on a bit of a wild goose chase.

The solution was simply a missed entry in application.json. In my case it was an omitted “assembly” section. Having said that, I did come across a few instances where people had the same problem when omitting commas etc.

Hopefully that’s able to get you on the right track!

Thanks,
Chris

Typography Component without a Line Break – Material-UI

Hey everyone,

UPDATE:
In new versions you now need to add a display attribute: display=”inline”

I’ve been working with Material-UI and ReactJS and had a bit of an issue with a Typography component generating an unwanted link break:

download (1)

To fix it, all I needed was the inline attribute. Once added the text appeared next to the form element instead of below:
Capture
download (3)

Change i2c address of ina219

Hi everyone,

I wanted to use ina219 with pca9685 but they shared the same i2c address 0x4:
download0.

Luckily, there’s a fairly easy fix for this. All we need to do is solder two pins together. We’re going to bridge a0 and this will change our address to 0x41.

In order to check these run sudo i2cdetect -y 1 pm the raspberry pi:
download

After soldering it becomes:
download

You can solder a combination of pins for different addresses:
None = 0x40 (default)
A0 = 0x41
A1 = 0x44 (the one I’ve soldered to get 44)
A0 + A1 = 0x45

A4988 Stepper motor RaspberryPi

We’re using a 42shd0034-20B Geetech stepping motor taken from a 3d printer:
download

We’ll be driving it with an A4988 stepper motor controller. You can pick up five packs of these for less than $2 online – definitely worth having a few extras around:
download

The datasheet is available here: https://www.pololu.com/file/download/A4988.pdf?file_id=0J450

The following diagram illustrates what we’ll be doing:
download

Once everything is connected it’ll end up looking something like this:
download

To start, connect your stepping and direction pins. I’ve used GPIO16 for stepping and GPIO21 for direction:
download

Each time GPIO16 is set to HIGH it will make the stepper motor take one step. When the direction pin is HIGH the stepper motor will go clockwise, when it’s LOW, anti-clockwise.

If you’re not using the sleep functionality, connect the RESET and SLP pins together and then wire them directly to 3.3v:
download

Using a separate power source wire 12v to the GND and VMOT pins. You should also place a capacitor across these pins as close to the board as possible. Generally the longest leg is positive. You’ll also need to connect the external GND to the Raspberry Pi’s GND:
download

Connect the four pins of the stepper motor:
download

Connect the A4988 to 3.3v and common GND:
download

The code is pretty straight forward but I’ve provided a class below to help you get started:


# System imports
import RPi.GPIO as GPIO
from time import sleep

class StepperHandler():

__CLOCKWISE = 1
__ANTI_CLOCKWISE = 0

def __init__(self, stepPin, directionPin, delay=0.208, stepsPerRevolution=200):

# Configure instance
self.CLOCKWISE = self.__CLOCKWISE
self.ANTI_CLOCKWISE = self.__ANTI_CLOCKWISE
self.StepPin = stepPin
self.DirectionPin = directionPin
self.Delay = delay
self.RevolutionSteps = stepsPerRevolution
self.CurrentDirection = self.CLOCKWISE
self.CurrentStep = 0

# Setup gpio pins
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(self.StepPin, GPIO.OUT)
GPIO.setup(self.DirectionPin, GPIO.OUT)

def Step(self, stepsToTake, direction = __CLOCKWISE):

print("Step Pin: " + str(self.StepPin) + " Direction Pin: " + str(self.DirectionPin) + " Delay: " + str(self.Delay))
print("Taking " + str(stepsToTake) + " steps.")

# Set the direction
GPIO.output(self.DirectionPin, direction)

# Take requested number of steps
for x in range(stepsToTake):
print("Step " + str(x))
GPIO.output(self.StepPin, GPIO.HIGH)
self.CurrentStep += 1
sleep(self.Delay)
GPIO.output(self.StepPin, GPIO.LOW)
sleep(self.Delay)

# Define pins
STEP_PIN = 16
DIRECTION_PIN = 21

# Create a new instance of our stepper class (note if you're just starting out with this you're probably better off using a delay of ~0.1)
stepperHandler = StepperHandler(STEP_PIN, DIRECTION_PIN, 0.0025)

# Go forwards once
stepperHandler.Step(200)

# Go backwards once
stepperHandler.Step(200, stepperHandler.ANTI_CLOCKWISE)