Присоединяйтесь в ICacheEntryFilter в фильтрах в ignite.net - PullRequest
0 голосов
/ 16 декабря 2018

Я пытаюсь реализовать пространственный запрос в Ignite.net, и это моя функция для нахождения географических точек в области

        public List<GeoPointDto> GetPointsInZone(CartesianPoint[] cartesianPoints, string zoneId)
    {
        List<GeoPointDto> reslt = new List<GeoPointDto>();

        var scanQuery = new ScanQuery<string, GeoPoint>(new SearchPointsInArea(cartesianPoints, zoneId, cache));
        IQueryCursor<ICacheEntry<string, GeoPoint>> queryCursor = cache.Query(scanQuery);

        var res = queryCursor.GetAll();
        foreach (ICacheEntry<string, GeoPoint> cacheEntry in res)
        {
            var tempPoint = new Dto.Point()
            {
                Latitude = cacheEntry.Value.Location.PointOnSurface.Y,
                Longitude = cacheEntry.Value.Location.PointOnSurface.X
            };
            reslt.Add(new GeoPointDto()
            {
                CreateDate = cacheEntry.Value.CreateDate,
                SerialNumber = "",
                Point = tempPoint
            });
        }

        return reslt;
    }

Как вы можете видеть, я отправляю фильтр с запросом сканирования для зажиганиякеш, и это его код

    public class SearchPointsInArea : ICacheEntryFilter<string, GeoPoint>
{
    private ICache<string, GeoPoint> cache;
    private CartesianPoint[] BorderPoints { get; set; }
    private string ZoneId { get; set; }
    public SearchPointsInArea(CartesianPoint[] _borderPoints, string _zoneId, ICache<string, GeoPoint> _cache)
    {
        this.BorderPoints = _borderPoints;
        this.ZoneId = _zoneId;
        this.cache = _cache;
    }

    public bool Invoke(ICacheEntry<string, GeoPoint> entry)
    {
        CartesianPoint point = new CartesianPoint()
        {
            Y = entry.Value.Location.PointOnSurface.Y,
            X = entry.Value.Location.PointOnSurface.X
        };
        if (IsInPolygon(BorderPoints, point))
        {
            var queryString = "select count(p.SerialNumber) from GeoPoint as p inner join " +
                "Device as d on d.SerialNumber = p.SerialNumber inner join " +
                "Vehicle as v on v.Id = d.VehicleId " +
                "where v.ZoneId like (?) and p.SerialNumber like (?)";
            IFieldsQueryCursor query = cache.Query(new SqlFieldsQuery(queryString, ZoneId, entry.Value.SerialNumber));
            var res = query.GetAll().First();

            if (Int32.Parse(res.ToString()) > 0)
                return true;
            else
                return false;
        }
        else
        {
            return false;
        }

    }

    public bool IsInPolygon(CartesianPoint[] poly, CartesianPoint point)
    {
        var coef = poly.Skip(1).Select((p, i) =>
                                        (point.Y - poly[i].Y) * (p.X - poly[i].X)
                                      - (point.X - poly[i].X) * (p.Y - poly[i].Y))
                                .ToList();

        if (coef.Any(p => p == 0))
            return true;

        for (int i = 1; i < coef.Count(); i++)
        {
            if (coef[i] * coef[i - 1] < 0)
                return false;
        }
        return true;
    }
}

Как вы можете видеть, у меня есть функция IsInPolygon для проверки точек в области, а затем SqlFieldQuery для проверки того, что они находятся в этой области (объект GeoPoint не имеет ZoneId имежду ними есть еще 2 объекта), но я получил эту ошибку

System.Runtime.Serialization.SerializationException: 'Serializing delegates is not supported on this platform.'

На самом деле мне нужно соединение в моем фильтре для достижения моей цели.Есть ли способ к этому?

1 Ответ

0 голосов
/ 14 января 2019

Вы не должны пытаться передать ICache для сериализации и отправки на удаленный сервер.Вместо этого вам следует использовать [InstanceResource] для внедрения удаленного экземпляра Ignite в ваш Фильтр , как показано в документах , запрашивать кэш во время фильтрации.

...