I have a geoJSON objects and I want to route between waypoints on my geoJSON file.
{
"type":"FeatureCollection",
"generator":"JOSM",
"bbox":[
23.4668,
58.9198,
23.6412,
58.974
],
"features":[
{
"type":"Feature",
"properties":{
"wheelchair":"yes",
"smoothness":"bad",
"surface":"crushed stones"
},
"geometry":{
"type":"Point",
"coordinates":[
23.53359252,
58.95034587858
]
}
},
{
"type":"Feature",
"properties":{
"wheelchair":"yes",
"addr:housename":"Saue kohvik",
"amenity":"pub",
"name":"Saue kohvik"
},
"geometry":{
"type":"Point",
"coordinates":[
23.5361382,
58.9473236
]
}
},
{
"type":"Feature",
"properties":{
"wheelchair":"yes",
"smoothness":"intermediate",
"highway":"footway"
},
"geometry":{
"type":"LineString",
"coordinates":[
[
23.5410658,
58.9406213
],
[
23.5410936,
58.9408252
],
[
23.541092,
58.9408358
],
[
23.5410706,
58.9410896
],
[
23.5410448,
58.9412609
],
[
23.541028,
58.9413309
],
[
23.5409993,
58.9414512
],
[
23.5408984,
58.9416477
],
[
23.5408677,
58.9416962
],
[
23.5407571,
58.9418706
],
[
23.5405886,
58.9421204
],
[
23.5405302,
58.9422071
],
[
23.5403894,
58.9423888
],
[
23.5401636,
58.9426413
],
[
23.5400953,
58.9426593
],
[
23.5399336,
58.9428447
],
[
23.5399287,
58.9428504
],
[
23.5399434,
58.9428895
],
[
23.5394702,
58.9434341
],
[
23.5394296,
58.943468
],
[
23.5389324,
58.9439879
],
[
23.5384256,
58.9445103
],
[
23.5381597,
58.9447992
],
[
23.5377425,
58.9452314
],
[
23.5375449,
58.9454551
]
]
}
},
{
"type":"Feature",
"properties":{
"wheelchair":"yes",
"highway":"footway"
},
"geometry":{
"type":"LineString",
"coordinates":[
[
23.5408677,
58.9416962
],
[
23.541045,
58.9417267
],
[
23.5412157,
58.9417564
]
]
}
}
]
}
And my question is: Can I route between places inside my file "routing only on these LineStrings where properties are "wheelchair":"yes"and "highway":"footway". And routing cant use LineStrings where property is only "highway":"footway".
Is it possible when I'm using mapbox direction service?
I made my own openstreetmap with my custom properties, but know I'm stuck, I don't know how do route in that map, because routing can only call out on these ways (linestrings and points) where one property is wheelchair="yes".
You could use L.mapbox.FeatureLayer to render your featurecollection in combination with a filter:
var featureLayer = L.mapbox.featureLayer('data.geo.json').addTo(map);
var filter = function (feature) {
// Check if feature is a linestring
if (feature.geometry.type == 'Linestring') {
// Check if has property wheelchair and value is yes
if (feature.properties.hasOwnProperty('wheelchair') &&
feature.properties.wheelchair === 'yes') {
// Check if has property highway and value is footway
if (!feature.properties.hasOwnProperty('highway') ||
feature.properties.highway === 'footway') {
// highway absent or highway is footway
return true;
} else {
// highway found and value is not footway
return false;
}
} else {
// Wheelchair absent or value isn't yes
return false;
}
} else {
// Not a linestring
return true;
}
}
featureLayer.on('ready', function () {
featureLayer.setFilter(filter);
});
Reference for L.mapbox.featureLayer: https://www.mapbox.com/mapbox.js/api/v2.1.5/l-mapbox-featurelayer/
Related
I have a simple scatterplot with two datasets: active and passive:
const data = {
"datasets": [{
"label": "Active",
"sentences": [
"A1",
"A2",
"A3"
],
"data": [
[
"0.4340433805869016",
"0.12813240157479788"
],
[
"-0.39983629799199083",
"0.12125799115087213"
],
[
"-0.04289228113339527",
"0.10106119377169194"
]
],
"borderColor": "#43a047",
"backgroundColor": "#7cb342"
},
{
"label": "Passive",
"sentences": [
"P1",
"P2",
"P3"
],
"data": [
[
"0.4295487808020268",
"0.19271652809947026"
],
[
"-0.4438451670978469",
"-0.08848766134414247"
],
[
"-0.10789534989054622",
"0.08013654263956245"
]
],
"borderColor": "#1e88e5",
"backgroundColor": "#039be5"
}
],
"labels": []
};
new Chart(document.getElementById("sentences"), {
type: "scatter",
data: data,
options: {
responsive: true,
plugins: {
legend: {
position: "top",
},
tooltip: {
callbacks: {
label: ctx => ctx.dataset.sentences[ctx.dataIndex]
}
}
}
}
});
(https://jsfiddle.net/br5dhpwx/)
Currently this renders fine as is:
However, I want to draw a line between the corresponding data points on mouseover. I.e. A1-P1, A2-P2, A3-P3, etc.
It should look something like this:
I tried to use the setHoverStyle event, but, so far, wasn't successful.
You can use a custom plugin for this:
const EXPANDO_KEY = 'customLinePlugin';
const data = {
"datasets": [{
"label": "Active",
"sentences": [
"A1",
"A2",
"A3"
],
"data": [
[
"0.4340433805869016",
"0.12813240157479788"
],
[
"-0.39983629799199083",
"0.12125799115087213"
],
[
"-0.04289228113339527",
"0.10106119377169194"
]
],
"borderColor": "#43a047",
"backgroundColor": "#7cb342"
},
{
"label": "Passive",
"sentences": [
"P1",
"P2",
"P3"
],
"data": [
[
"0.4295487808020268",
"0.19271652809947026"
],
[
"-0.4438451670978469",
"-0.08848766134414247"
],
[
"-0.10789534989054622",
"0.08013654263956245"
]
],
"borderColor": "#1e88e5",
"backgroundColor": "#039be5"
}
],
"labels": []
};
const plugin = {
id: "customLine",
afterInit: (chart) => {
chart[EXPANDO_KEY] = {
index: null
}
},
afterEvent: (chart, evt) => {
const activeEls = chart.getElementsAtEventForMode(evt.event, 'nearest', {
intersect: true
}, true)
if (activeEls.length === 0) {
chart[EXPANDO_KEY].index = null
return;
}
chart[EXPANDO_KEY].index = activeEls[0].index;
},
beforeDatasetsDraw: (chart, _, opts) => {
const {
ctx
} = chart;
const {
index
} = chart[EXPANDO_KEY];
if (index === null) {
return;
}
const dp0 = chart.getDatasetMeta(0).data[index]
const dp1 = chart.getDatasetMeta(1).data[index]
ctx.lineWidth = opts.width || 0;
ctx.setLineDash(opts.dash || []);
ctx.strokeStyle = opts.color || 'black'
ctx.save();
ctx.beginPath();
ctx.moveTo(dp0.x, dp0.y);
ctx.lineTo(dp1.x, dp1.y);
ctx.stroke();
ctx.restore();
}
}
new Chart(document.getElementById("sentences"), {
type: "scatter",
data: data,
options: {
responsive: true,
plugins: {
customLine: {
dash: [2, 2],
color: 'red',
width: 2
},
legend: {
position: "top",
},
tooltip: {
callbacks: {
label: ctx => ctx.dataset.sentences[ctx.dataIndex]
}
}
}
},
plugins: [plugin]
});
<body>
<canvas id="sentences"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.2/chart.js"></script>
</body>
EDIT:
For some reason stack snippet in creation works but doesnt like so itself, so here is a fiddle link: https://jsfiddle.net/Leelenaleee/btux41dz/
I do have simple groupBy query in my prisma which looks like this:
const groupBy = await prisma.referral.groupBy({
by: ['recommenderId'],
_sum: {
points: true,
},
});
What I am looking for is the way to sort by this _sum value.
The current response is:
{
"groupBy": [
{
"_sum": {
"points": 20000
},
"recommenderId": 3
},
{
"_sum": {
"points": 19000
},
"recommenderId": 2
},
{
"_sum": {
"points": 34000
},
"recommenderId": 1
}
]
}
What I need is to get is:
{
"groupBy": [
{
"_sum": {
"points": 34000
},
"recommenderId": 1
},
{
"_sum": {
"points": 20000
},
"recommenderId": 3
},
{
"_sum": {
"points": 19000
},
"recommenderId": 2
},
]
}
Based on documentation (https://www.prisma.io/docs/concepts/components/prisma-client/filtering-and-sorting#sorting) I tried something like this:
const groupBy = await prisma.referral.groupBy({
by: ['recommenderId'],
_sum: {
points: true,
},
orderBy: [
{
_sum: 'desc',
},
],
});
But with code I'm getting error:
Argument _sum: Got invalid value 'desc' on prisma.groupByReferral.
Provided String, expected ReferralSumOrderByAggregateInput
You can use _sum on different fields at the same time, so you also need to provide field name that you want to sort on:
const groupBy = await prisma.referral.groupBy({
by: ['recommenderId'],
_sum: {
points: true,
},
orderBy: [
{
_sum: {
// Add `points` key here
points: 'desc'
}
},
],
});
I am running into an issue where I'm trying to grab some documents near the current document in a lookup. If I manually enter the lon/lat the following query will work but it fails with trying to use anything from the "let". How can I reference the location of the parent document in the geoNear in the lookup pipeline?
[
{
"$match":{
'assessed_improvement_value':{'$gt':500},
'sqft':{'$gt':500}
}
},
{
"$lookup":{
"from":"properties",
"let":{
'lon':{"$arrayElemAt":["$location.coordinates",0]},
'lat':{"$arrayElemAt":["$location.coordinates",1]},
},
'pipeline': [
{
"$geoNear": {
"near": { "type": "Point", "coordinates": [ "$$lon" , "$$lat" ] },
"distanceField": "distance",
"spherical": true
}
},
{"$limit":10}
],
"as":"comps",
}
},
{"$limit":10}
]
Update
The first method I posted was in fact a mess. I've now came up with a much cleaner solution. I hope this helps someone in the future
[
{
"$lookup":{
"from":"properties",
"let":{
'plon':{"$arrayElemAt":["$location.coordinates",0]},
'plat':{"$arrayElemAt":["$location.coordinates",1]},
},
'pipeline': [
{
"$addFields":{
"distance":{
"$function":{
"body":"""
function(plonRad,platRad, lonRad, latRad) {
var R = 6373.0;
var dlon = lonRad - plonRad;
var dlat = latRad - platRad;
if((dlon == 0) || (dlat == 0)) {
return 0;
}
var a = Math.pow(Math.sin(dlat / 2),2)+ Math.cos(platRad) * Math.cos(latRad) * Math.pow(Math.sin(dlon / 2),2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var dist = R * c;
return dist*0.621371;
}
""",
"args":[
{"$toDouble":{"$degreesToRadians":"$$plon"}},
{"$toDouble":{"$degreesToRadians":"$$plat"}},
{"$toDouble":{"$degreesToRadians":{"$arrayElemAt":["$location.coordinates",0]}}},
{"$toDouble":{"$degreesToRadians":{"$arrayElemAt":["$location.coordinates",1]}}}],
"lang":"js"
}
}
}
},
{
"$match":{
"distance":{"$gt":0}
}
},
{"$sort":{"distance":1}},
{"$limit":20}
],
"as":"comps",
}
}
]
I guess this is an old bug that was never fixed for whatever reason. This feels like a mess but it is a working solution. This manually calculates the distance in miles.
[
{
"$match":{
'assessed_improvement_value':{'$gt':500},
'sqft':{'$gt':500}
}
},
{
"$lookup":{
"from":"properties",
"let":{
'lon':{"$arrayElemAt":["$location.coordinates",0]},
'lat':{"$arrayElemAt":["$location.coordinates",1]},
},
'pipeline': [
{
"$addFields": {
'plonRad':{"$degreesToRadians":"$$lon"},
'platRad':{"$degreesToRadians":"$$lat"},
'lonRad':{"$degreesToRadians":{"$arrayElemAt":["$location.coordinates",0]}},
'latRad':{"$degreesToRadians":{"$arrayElemAt":["$location.coordinates",1]}},
}
},
{
'$addFields':{
"dlon":{
"$subtract":["$plonRad", "$lonRad"]
},
"dlat":{
"$subtract":["$platRad", "$latRad"]
},
}
},
{
"$addFields":{
'a':{
"$multiply":[
{
"$add":[
{
"$pow":[
{
"$sin":{
"$divide":["$dlat",2]
}
},
2
]
},
{
"$cos":"$platRad"
}
]
},
{
"$add":[
{
"$pow":[
{
"$sin":{
"$divide":["$dlon",2]
}
},
2
]
},
{
"$cos":"$latRad"
}
]
}
]
},
}
},
{
"$addFields":{
"c":{
"$atan2":[
{"$sqrt":"$a"},
{"$sqrt":{"$subtract":[1,"$a"]}}
]
}
}
},
{
"$addFields":{
"distance":{
"$divide":[
{"$multiply":[6373.0,"$c"]},
1609.34
]
}
}
},
{"$limit":10}
],
"as":"comps",
}
},
{"$limit":10}
]
I have the cloud formation template like below. Here I want to make the volumes all DeleteOnTermination as true. To achieve this I have included the BlockDeviceMappings section as only that allows setting value for DeleteOnTermination.
But I am getting error:
Invalid value '/dev/sdf' for unixDevice. Attachment point /dev/sdf is already in use
What am I doing wrong?
Should I remove the /dev/sdf from volume section and keep it only in BlockDeviceMappings?
"Resources":{
"INSc42a7c2eed094a79acd851bdc9772a13":{
"Type":"AWS::EC2::Instance",
"Properties":{
"InstanceType":"t2.micro",
"BlockDeviceMappings":[
{
"DeviceName":"/dev/sda1",
"Ebs":{
"VolumeSize":"50",
"DeleteOnTermination":"true"
}
},
{
"DeviceName":"/dev/sdf",
"Ebs":{
"VolumeSize":"100",
"DeleteOnTermination":"true"
}
}
],
"ImageId":"ami-6871a115",
"KeyName":"${aws_key_pair.KP6a0efc01a84c4103b648b57b425b0ca2.key_name}",
"NetworkInterfaces":[
{
"AssociatePublicIpAddress":"true",
"DeviceIndex":"0",
"SubnetId":"subnet-07f722e24335cea6f",
"GroupSet":[
"sg-0ed40ed2e6af3db09"
]
}
],
"Volumes":[
{
"Device":"/dev/sdf",
"VolumeId":{
"Ref":"Volume67430dc919ab486a887388695720e574"
}
}
],
"Tags":[
{
"Key":"Name",
"Value":"jagaranteamvoltest"
},
{
"Key":"vid",
"Value":"c42a7c2e-ed09-4a79-acd8-51bdc9772a13"
}
]
}
},
"Alias60d46c3715ee4a72a4d3739b951bd4e0":{
"Type":"AWS::KMS::Alias",
"Properties":{
"AliasName":"alias/KmsKeyVolTest",
"TargetKeyId":{
"Ref":"KmsKey60d46c3715ee4a72a4d3739b951bd4e0"
}
}
},
"KmsKey60d46c3715ee4a72a4d3739b951bd4e0":{
"Type":"AWS::KMS::Key",
"Properties":{
"Description":"key description sample",
"KeyPolicy":{
"Version":"2012-10-17",
"Statement":[
{
"Sid":"Allow access for Key Administrators",
"Effect":"Allow",
"Principal":{
"AWS":[
"${data.aws_caller_identity.current.arn}"
]
},
"Action":[
"kms:Create*",
"kms:Describe*",
"kms:Enable*",
"kms:List*",
"kms:Put*",
"kms:Update*",
"kms:Revoke*",
"kms:Disable*",
"kms:Get*",
"kms:Delete*",
"kms:TagResource",
"kms:UntagResource",
"kms:ScheduleKeyDeletion",
"kms:CancelKeyDeletion",
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:CreateGrant",
"kms:ListGrants",
"kms:DescribeKey",
"ec2:*"
],
"Resource":"*"
}
]
}
}
},
"Volume67430dc919ab486a887388695720e574":{
"Type":"AWS::EC2::Volume",
"DeletionPolicy":"Delete",
"Properties":{
"AutoEnableIO":"false",
"AvailabilityZone":"us-east-1a",
"Encrypted":"true",
"KmsKeyId":{
"Ref":"KmsKey60d46c3715ee4a72a4d3739b951bd4e0"
},
"Size":"15",
"VolumeType":"standard",
"Tags":[
{
"Key":"vid",
"Value":"67430dc9-19ab-486a-8873-88695720e574"
}
]
}
}
},
"Outputs":{
"caceedaacdbdca":{
"Description":"Instance ID",
"Value":{
"Ref":"INSc42a7c2eed094a79acd851bdc9772a13"
}
},
"dceeaadbbde":{
"Description":"KMS Id",
"Value":{
"Ref":"KmsKey60d46c3715ee4a72a4d3739b951bd4e0"
}
}
}
}
Keep only one /dev/sdf in your template. Either "AWS::EC2::Volume" or from BlockDeviceMappings Or Change the name for one drive. You can't keep two volumes with the same name.
I have 1000 number of JSON objects in text file. I want to retrieve only one JSON object for a particular duns number using PowerShell.
{
"organization":{
"duns":"024330410",
"dunsControlStatus":{
"operatingStatus":{
"description":"Active",
"dnbCode":9074
},
"isMarketable":false,
"isMailUndeliverable":false,
"isTelephoneDisconnected":null,
"isDelisted":false,
"subjectHandlingDetails":[
],
"fullReportDate":"2018-02-10"
},
"primaryName":"SRP Trucking LLC",
"multilingualPrimaryName":[
],
"tradeStyleNames":[
],
"websiteAddress":[
],
"telephone":[
],
"fax":[
],
"primaryAddress":{
"language":{
},
"addressCountry":{
"name":"United States",
"isoAlpha2Code":"US",
"fipsCode":"US"
},
"continentalRegion":{
"name":"North America"
},
"addressLocality":{
"name":"LAKE HAVASU CITY"
},
"minorTownName":null,
"addressRegion":{
"name":"Arizona",
"abbreviatedName":"AZ",
"fipsCode":"04"
},
"addressCounty":{
"name":"MOHAVE",
"fipsCode":"015"
},
"postalCode":"864035343",
"postalCodePosition":{
},
"streetNumber":null,
"streetName":null,
"streetAddress":{
"line1":"25 SOUTHWESTER LN",
"line2":null
},
"postOfficeBox":{
},
"latitude":34.488798,
"longitude":-114.301529,
"geographicalPrecision":{
"description":"Street Address Centroid",
"dnbCode":30257
},
"isRegisteredAddress":false,
"isResidentialAddress":null,
"statisticalArea":{
"cbsaName":"Lake Havasu City-Kingman AZ",
"cbsaCode":"29420",
"economicAreaOfInfluenceCode":"092",
"populationRank":{
"rankNumber":"7",
"rankDnBCode":10959,
"rankDescription":"100,000 to 249,999"
}
},
"locationOwnership":{
},
"premisesArea":{
"measurement":2915.0,
"unitDescription":"Square Foot",
"unitDnBCode":3848,
"reliabilityDescription":"Modelled",
"reliabilityDnBCode":9094
},
"isManufacturingLocation":null
},
"multilingualPrimaryAddress":[
],
"registeredAddress":{
},
"mailingAddress":{
},
"stockExchanges":[
],
"thirdPartyAssessment":[
],
"registrationNumbers":[
],
"industryCodes":[
{
"code":"484110",
"description":"General Freight Trucking, Local",
"typeDescription":"North American Industry Classification System 2017",
"typeDnBCode":30832,
"priority":1
},
{
"code":"1622",
"description":"Trucking",
"typeDescription":"D&B Hoovers Industry Code",
"typeDnBCode":25838,
"priority":1
},
{
"code":"4212",
"description":"Local trucking operator",
"typeDescription":"US Standard Industry Code 1987 - 4 digit",
"typeDnBCode":399,
"priority":1
},
{
"code":"42120000",
"description":"Local trucking, without storage",
"typeDescription":"D&B Standard Industry Code",
"typeDnBCode":3599,
"priority":1
},
{
"code":"E",
"description":"Transportation, Communications, Electric, Gas and Sanitary Services",
"typeDescription":"D&B Standard Major Industry Code",
"typeDnBCode":24657,
"priority":1
}
],
"businessEntityType":{
"description":"Unknown",
"dnbCode":0
},
"controlOwnershipDate":"2015",
"startDate":"2015",
"controlOwnershipType":{
},
"isAgent":null,
"isImporter":null,
"isExporter":null,
"numberOfEmployees":[
{
"value":1,
"informationScopeDescription":"Consolidated",
"informationScopeDnBCode":9067,
"reliabilityDescription":"Modelled",
"reliabilityDnBCode":9094,
"employeeCategories":[
],
"trend":[
]
},
{
"value":1,
"informationScopeDescription":"Individual",
"informationScopeDnBCode":9066,
"reliabilityDescription":"Modelled",
"reliabilityDnBCode":9094,
"employeeCategories":[
],
"trend":[
]
}
],
"financials":[
{
"financialStatementToDate":"2016-10-01",
"financialStatementDuration":null,
"informationScopeDescription":null,
"informationScopeDnBCode":null,
"reliabilityDescription":"Modelled",
"reliabilityDnBCode":9094,
"unitCode":"Single Units",
"accountantName":null,
"yearlyRevenue":[
{
"value":57815.0,
"currency":"USD",
"trend":[
]
}
]
}
],
"mostSeniorPrincipals":[
{
"givenName":"Debbie",
"familyName":"Pickering",
"fullName":"Debbie Pickering",
"namePrefix":null,
"nameSuffix":null,
"gender":null,
"jobTitles":[
{
"title":"Owner"
}
],
"managementResponsibilities":[
{
"description":"Owner",
"mrcCode":"A0A1"
}
]
}
],
"currentPrincipals":[
],
"socioEconomicInformation":{
"isMinorityOwned":null,
"isSmallBusiness":true
},
"isStandalone":true,
"corporateLinkage":{
}
}
}
PS direct have to JSON cmdlets which can serve your purpose:
Take the JSON string in a variable as $variable1, then use:
$variable1 | ConvertFrom-Json
and later you can use Convertto-Json to convert that to JSON also with where-object
Hope it helps. Just formed the answer from Tomalak