private List <Feature> MapMultiple(VectorPrescription prescription)
        {
            List <Feature> features = new List <Feature>();

            double outOfFieldRate = -1.0;               // something save to compare with

            if (prescription.OutOfFieldRate != null)
            {
                outOfFieldRate = prescription.OutOfFieldRate.Value.Value;
            }

            foreach (var shaperate in prescription.RxShapeLookups)
            {
                int index = 0;
                if (shaperate.Shape != null && shaperate.Shape.Polygons.Count > 0)
                {
                    foreach (var adaptPolygon in shaperate.Shape.Polygons)
                    {
                        Dictionary <string, object> properties = new Dictionary <string, object>();
                        RxProductLookup             product    = prescription.RxProductLookups.Where(r => r.Id.ReferenceId == shaperate.Rates[index].RxProductLookupId).FirstOrDefault();
                        if (product != null)
                        {
                            properties.Add("productId", product.ProductId);
                            Product adaptProduct = _dataModel.Catalog.Products.Where(p => p.Id.ReferenceId == product.ProductId).FirstOrDefault();
                            if (adaptProduct != null)
                            {
                                properties.Add("productDescription", adaptProduct.Description);
                                properties.Add("productType", adaptProduct.ProductType.ToString());
                            }
                            properties.Add("productCode", product.Representation.Code);
                            properties.Add("productUom", product.UnitOfMeasure.Code);
                        }
                        else
                        {
                            properties.Add("productId", shaperate.Rates[index].RxProductLookupId);
                        }
                        properties.Add("rate", shaperate.Rates[index++].Rate);

                        features.Add(new Feature(PolygonMapper.MapPolygon(adaptPolygon, _properties.AffineTransformation), properties));
                    }
                }
            }

            return(features);
        }
        private Feature Map(VectorPrescription prescription)
        {
            Feature feature = null;
            Dictionary <string, object> properties = new Dictionary <string, object>();

            // SpatialPrescription: not sure these rates mean anything for the geojson output
            double outOfFieldRate = -1.0;               // something save to compare with

            if (prescription.OutOfFieldRate != null)
            {
                properties.Add("OutOfFieldRate", prescription.OutOfFieldRate.Value.Value);
                outOfFieldRate = prescription.OutOfFieldRate.Value.Value;
            }
            if (prescription.LossOfGpsRate != null)
            {
                properties.Add("LossOfGpsRate", prescription.LossOfGpsRate.Value.Value);
            }

            double minRate = double.MaxValue;
            double maxRate = -1;

            foreach (var shaperate in prescription.RxShapeLookups)
            {
                if (shaperate.Shape != null && shaperate.Shape.Polygons.Count > 0)
                {
                    foreach (var rate in shaperate.Rates)
                    {
                        if (rate.Rate != outOfFieldRate)
                        {
                            minRate = Math.Min(minRate, rate.Rate);
                            maxRate = Math.Max(maxRate, rate.Rate);
                        }
                    }
                }
                else                 // outoffield
                {
                    foreach (var rate in shaperate.Rates)
                    {
                        RxProductLookup product = prescription.RxProductLookups.Where(r => r.Id.ReferenceId == rate.RxProductLookupId).FirstOrDefault();
                        if (product == null)
                        {
                            Console.WriteLine("outoffield rate? " + rate.Rate + " " + rate.RxProductLookupId);
                        }
                        else
                        {
                            Console.WriteLine("outoffield rate? " + rate.Rate + " " + rate.RxProductLookupId + " " + product.Representation.Code);
                        }
                    }
                }
            }
            properties.Add("MinRate", minRate);
            properties.Add("MaxRate", maxRate);
            List <Dictionary <string, object> > products = new List <Dictionary <string, object> > {
            };

            foreach (var rxproduct in prescription.RxProductLookups)
            {
                if (products.Where(p => p.ContainsKey("productId") && (int)p["productId"] == rxproduct.ProductId).FirstOrDefault() == null)
                {
                    Dictionary <string, object> product = new Dictionary <string, object>();
                    product.Add("productId", rxproduct.ProductId);
                    product.Add("productCode", rxproduct.Representation.Code);
                    product.Add("productUom", rxproduct.UnitOfMeasure.Code);
                    Product adaptProduct = _dataModel.Catalog.Products.Where(p => p.Id.ReferenceId == rxproduct.ProductId).FirstOrDefault();
                    if (adaptProduct != null)
                    {
                        product.Add("productDescription", adaptProduct.Description);
                        product.Add("productType", adaptProduct.ProductType.ToString());                         // or via GetName?
                    }
                    products.Add(product);
                }
            }
            properties.Add("Products", products.ToArray());

            if (prescription.BoundingBox != null)
            {
                GeoJSON.Net.Geometry.Polygon polygon = PolygonMapper.MapBoundingBox(prescription.BoundingBox, _properties.AffineTransformation);                  // MinX, MinY, MaxX, MaxY
                feature = new Feature(polygon, properties);
            }
            else
            {
                // @ToDo dissolve multipolygon or use Envelope?
                // NetTopologySuite.Operation.Union.CascadedPolygonUnion
                // NetTopologySuite.Algorithm.MinimumDiameter.GetMinimumRectangle
                var polygons = new List <GeoJSON.Net.Geometry.Polygon>();
                foreach (var shaperate in prescription.RxShapeLookups)
                {
                    if (shaperate.Shape != null && shaperate.Shape.Polygons.Count > 0)
                    {
                        foreach (var adaptPolygon in shaperate.Shape.Polygons)
                        {
                            GeoJSON.Net.Geometry.Polygon polygon = PolygonMapper.MapPolygon(adaptPolygon, _properties.AffineTransformation);
                            if (polygon != null)
                            {
                                polygons.Add(polygon);
                            }
                        }
                    }
                }
                feature = new Feature(new GeoJSON.Net.Geometry.MultiPolygon(polygons), properties);
            }

            return(feature);
        }