Exemplo n.º 1
0
        private static (Operation operation, OperationMxProcessing operationPrescription) BuildTheGeoJsonOutput(RuleResult collectRuleResult, List <Value> values, Operation buildGeoJsonOperation = null)
        {
            var cityCount = values.Count;

            // Build the Javascript template for creating the entire GeoJSON Value
            var valueBody = "{\"type\":\"FeatureCollection\",\"features\":[";

            for (var ix = 0; ix < cityCount; ix++)
            {
                if (ix > 0)
                {
                    valueBody += ",";
                }
                valueBody += $"${{{ix}}}";
            }
            valueBody += "]}";
            var valueTemplate = $"{{JSON.parse('{valueBody}')}}";

            // Add an Operation to reference the collect Rule and merge all of the results into one GeoJSON
            if (buildGeoJsonOperation == null)
            {
                var opKey = values.OperandKey(EntityType.Value);

                buildGeoJsonOperation = collectRuleResult.CreateUpdateOperation(new[] { opKey }, GuidHelpers.NewTimeUuid(), valueTemplate);
            }
            else
            {
                var opKey = values.OperandKey(EntityType.Value, buildGeoJsonOperation.Operands[0].EntityId);

                buildGeoJsonOperation =
                    buildGeoJsonOperation.RecreateUpdateOperation(collectRuleResult, new[] { opKey }, valueTemplate);
            }

            var buildGeoJsonPrescription = buildGeoJsonOperation.AddUpdate();

            return(buildGeoJsonOperation, buildGeoJsonPrescription);
        }
Exemplo n.º 2
0
        private static (List <Operation> operations, List <OperationMxProcessing> operationPrescriptions) BuildTheCityDistances(RuleResult cityRuleResults, List <Value> values)
        {
            var operations             = new List <Operation>();
            var operationPrescriptions = new List <OperationMxProcessing>();

            // Build the Javascript template for calculating the length of each connecting GeoJSON line
            // Concept - Id of this city, then formula to calculate each distance and output the result as a sorted list.
            const string cityATempl   = "{{'cityAId':'{0}','destinations':[";
            const string lonTempl     = "JSON.parse('${{{0}}}')['geometry']['coordinates'][0]";
            const string latTempl     = "JSON.parse('${{{0}}}')['geometry']['coordinates'][1]";
            const string getDistTempl = "{{'cityBId':'{0}','distance':Math.pow(Math.pow({1} - {2}, 2) + Math.pow({3} - {4}, 2), 0.5),'usage':'not set'}}";

            for (var ix = 0; ix < values.Count; ix++)
            {
                var jTemplate = new StringBuilder();
                jTemplate.AppendLine("[");

                jTemplate.AppendFormat(cityATempl, values[ix].EntityId);
                jTemplate.AppendLine();
                var cityALonTempl = string.Format(lonTempl, ix);
                var cityALatTempl = string.Format(latTempl, ix);

                var needsComma = false;
                for (var jx = 0; jx < values.Count; jx++)
                {
                    if (ix == jx)
                    {
                        continue;
                    }

                    var cityBLonTempl     = string.Format(lonTempl, jx);
                    var cityBLatTempl     = string.Format(latTempl, jx);
                    var cityAtoBDistTempl = string.Format(getDistTempl, values[jx].EntityId, cityALonTempl, cityBLonTempl, cityALatTempl, cityBLatTempl);

                    if (needsComma)
                    {
                        jTemplate.AppendLine(",");
                    }
                    jTemplate.Append(cityAtoBDistTempl);
                    if (!needsComma)
                    {
                        needsComma = true;
                    }
                }
                jTemplate.AppendLine();
                jTemplate.AppendLine("].sort(function(a, b) {return a.distance - b.distance;})");
                // Adding a slice at the end (for the 10 shortest paths) reduce the overall file size but did not seem to reduce processing time
                // jTemplate.AppendLine("].sort(function(a, b) {return a.distance - b.distance;}).slice(0, 10)");
                jTemplate.AppendLine("}");
                jTemplate.AppendLine("]");

                var jTempl = jTemplate.ToString();

                // Although the source values are always the same we need a new OperandKey each time
                // for each new Value to be generated
                var opKeys = new[] { values.OperandKey(EntityType.Value) };

                // Add an Operation to reference the collect Rule and merge all of the results into one GeoJSON
                var buildCityDistancesOperation    = cityRuleResults.CreateUpdateOperation(opKeys, GuidHelpers.NewTimeUuid(), jTempl);
                var buildCityDistancesPrescription = buildCityDistancesOperation.AddUpdate();

                operations.Add(buildCityDistancesOperation);
                operationPrescriptions.Add(buildCityDistancesPrescription);
            }

            return(operations, operationPrescriptions);
        }